//
//  StatisticsService.swift
//  LotteryTracker
//
//  Created by aaa on 2026/1/22.
//

import Foundation
internal import CoreData
import Combine

class StatisticsService: ObservableObject {
    private let context: NSManagedObjectContext
    
    // 添加 Combine 发布者管理
    private var cancellables = Set<AnyCancellable>()
    
    // 添加缓存
    private var cachedMonthlyStats: MonthlyStats?
    private var cachedTypeDistribution: [TypeDistribution]?
    private var cachedProfitTrend: [DailyProfit]?
    private var lastRefreshTime: Date?
    private let cacheDuration: TimeInterval = 60 // 缓存60秒
    
    // 发布统计数据
    @Published var monthlyStats: MonthlyStats = MonthlyStats()
    @Published var typeDistribution: [TypeDistribution] = []
    @Published var profitTrend: [DailyProfit] = []
    @Published var isLoading: Bool = false
    
    init(context: NSManagedObjectContext) {
        self.context = context
        setupNotificationListeners()  // 添加通知监听
    }
    
    // 设置通知监听器
    private func setupNotificationListeners() {
        // 监听数据更新通知
        NotificationCenter.default.publisher(for: .ticketsUpdated)
            .sink { [weak self] notification in
                guard let self = self else { return }
                
                // 检查是否是清空操作（通过 userInfo 判断）
                if let userInfo = notification.userInfo,
                   let isClearOperation = userInfo["isClearOperation"] as? Bool,
                   isClearOperation {
                    print("📢 收到清空数据通知，清空统计缓存")
                    self.clearCacheImmediately()
                } else {
                    print("📢 收到数据更新通知，刷新统计")
                    // 异步刷新数据
                    Task {
                        await self.forceRefresh()
                    }
                }
            }
            .store(in: &cancellables)
        
        // 监听应用重置通知（如果有的话）
        NotificationCenter.default.publisher(for: .appReset)
            .sink { [weak self] _ in
                print("📢 收到应用重置通知，清空统计缓存")
                self?.clearCacheImmediately()
            }
            .store(in: &cancellables)
    }
    
    // 清空所有缓存数据（立即执行，在主线程）
    private func clearCacheImmediately() {
        DispatchQueue.main.async {
            self.cachedMonthlyStats = nil
            self.cachedTypeDistribution = nil
            self.cachedProfitTrend = nil
            self.lastRefreshTime = nil
            
            // 重置发布的数据
            self.monthlyStats = MonthlyStats()
            self.typeDistribution = []
            self.profitTrend = []
            
            print("🗑️ 统计缓存已立即清空")
        }
    }
    
    // 清空缓存（公开方法）
    func clearCache() {
        clearCacheImmediately()
    }
    
    // 强制刷新数据（忽略缓存）
    func forceRefresh() async {
        // 清空缓存
        clearCache()
        
        // 重新加载数据
        await loadAllStatistics()
    }
    
    // 异步加载所有统计数据
    func loadAllStatistics() async {
        await MainActor.run {
            isLoading = true
        }
        
        // 并行加载不同类型的数据
        async let monthly = loadMonthlyStatsAsync()
        async let distribution = loadTypeDistributionAsync()
        async let trend = loadProfitTrendAsync(days: 30)
        
        // 等待所有数据加载完成
        let (monthlyResult, distributionResult, trendResult) = await (monthly, distribution, trend)
        
        await MainActor.run {
            self.monthlyStats = monthlyResult
            self.typeDistribution = distributionResult
            self.profitTrend = trendResult
            self.isLoading = false
            
            // 更新缓存
            self.cachedMonthlyStats = monthlyResult
            self.cachedTypeDistribution = distributionResult
            self.cachedProfitTrend = trendResult
            self.lastRefreshTime = Date()
            
            print("📊 统计数据加载完成")
        }
    }
    
    // 异步加载月度统计
    private func loadMonthlyStatsAsync() async -> MonthlyStats {
        // 检查缓存
        if let cached = cachedMonthlyStats,
           let lastRefresh = lastRefreshTime,
           Date().timeIntervalSince(lastRefresh) < cacheDuration {
            return cached
        }
        
        return await withCheckedContinuation { continuation in
            DispatchQueue.global(qos: .userInitiated).async {
                let request = LotteryTicket.fetchRequest()
                
                guard let tickets = try? self.context.fetch(request) else {
                    continuation.resume(returning: MonthlyStats())
                    return
                }
                
                let calendar = Calendar.current
                let now = Date()
                
                // 获取本月数据
                let currentMonthTickets = tickets.filter { ticket in
                    guard let date = ticket.date else { return false }
                    return calendar.isDate(date, equalTo: now, toGranularity: .month)
                }
                
                // 获取上月数据
                let lastMonth = calendar.date(byAdding: .month, value: -1, to: now)!
                let lastMonthTickets = tickets.filter { ticket in
                    guard let date = ticket.date else { return false }
                    return calendar.isDate(date, equalTo: lastMonth, toGranularity: .month)
                }
                
                let stats = MonthlyStats(
                    currentMonth: self.calculateStats(for: currentMonthTickets),
                    lastMonth: self.calculateStats(for: lastMonthTickets)
                )
                
                continuation.resume(returning: stats)
            }
        }
    }
    
    // 异步加载类型分布
    private func loadTypeDistributionAsync() async -> [TypeDistribution] {
        // 检查缓存
        if let cached = cachedTypeDistribution,
           let lastRefresh = lastRefreshTime,
           Date().timeIntervalSince(lastRefresh) < cacheDuration {
            return cached
        }
        
        return await withCheckedContinuation { continuation in
            DispatchQueue.global(qos: .userInitiated).async {
                let request = LotteryTicket.fetchRequest()
                
                guard let tickets = try? self.context.fetch(request) else {
                    continuation.resume(returning: [])
                    return
                }
                
                var distribution: [LotteryType: Float] = [:]
                let totalAmount = tickets.reduce(0) { $0 + $1.amount }
                
                for ticket in tickets {
                    distribution[ticket.lotteryType, default: 0] += ticket.amount
                }
                
                let result = distribution.map { type, amount in
                    TypeDistribution(
                        type: type,
                        amount: amount,
                        percentage: totalAmount > 0 ? Float((amount / totalAmount)) * 100 : 0
                    )
                }.sorted { $0.amount > $1.amount }
                
                continuation.resume(returning: result)
            }
        }
    }
    
    // 异步加载盈亏趋势
    private func loadProfitTrendAsync(days: Int) async -> [DailyProfit] {
        // 检查缓存
        if let cached = cachedProfitTrend,
           let lastRefresh = lastRefreshTime,
           Date().timeIntervalSince(lastRefresh) < cacheDuration {
            return cached
        }
        
        return await withCheckedContinuation { continuation in
            DispatchQueue.global(qos: .userInitiated).async {
                let request = LotteryTicket.fetchRequest()
                
                guard let tickets = try? self.context.fetch(request) else {
                    continuation.resume(returning: [])
                    return
                }
                
                let calendar = Calendar.current
                let endDate = Date()
                let startDate = calendar.date(byAdding: .day, value: -days, to: endDate)!
                
                var dailyProfits: [Date: Float] = [:]
                
                for ticket in tickets {
                    guard let date = ticket.date else { continue }
                    let dayStart = calendar.startOfDay(for: date)
                    
                    if dayStart >= startDate && dayStart <= endDate {
                        dailyProfits[dayStart, default: 0] += ticket.profit
                    }
                }
                
                // 填充缺失的日期
                var result: [DailyProfit] = []
                var currentDate = startDate
                
                while currentDate <= endDate {
                    let profit = dailyProfits[currentDate] ?? 0
                    result.append(DailyProfit(date: currentDate, profit: profit))
                    currentDate = calendar.date(byAdding: .day, value: 1, to: currentDate)!
                }
                
                continuation.resume(returning: result)
            }
        }
    }
    
    // 计算统计数据
    private func calculateStats(for tickets: [LotteryTicket]) -> MonthStats {
        let totalSpent = tickets.reduce(0) { $0 + $1.amount }
        let totalPrize = tickets.reduce(0) { $0 + $1.prizeAmount }
        let profit = totalPrize - totalSpent
        
        let winningTickets = tickets.filter { $0.ticketStatus == .won }.count
        // 修复：winningTickets 已经是 Int，不需要 .count
        let winRate = tickets.isEmpty ? 0 : Float(winningTickets) / Float(tickets.count) * 100
        
        return MonthStats(
            ticketCount: Int16(tickets.count),
            totalSpent: totalSpent,
            totalProfit: profit,
            winRate: winRate,
            averageBet: tickets.isEmpty ? 0 : totalSpent / Float(tickets.count)
        )
    }
}

// 数据模型
struct MonthlyStats {
    let currentMonth: MonthStats
    let lastMonth: MonthStats
    
    init(currentMonth: MonthStats = MonthStats(), lastMonth: MonthStats = MonthStats()) {
        self.currentMonth = currentMonth
        self.lastMonth = lastMonth
    }
    
    var profitChange: Float {
        guard lastMonth.totalSpent > 0 else { return 0 }
        return ((currentMonth.totalProfit - lastMonth.totalProfit) / lastMonth.totalProfit) * 100
    }
}

struct MonthStats {
    let ticketCount: Int16
    let totalSpent: Float
    let totalProfit: Float
    let winRate: Float
    let averageBet: Float
    
    init(
        ticketCount: Int16 = 0,
        totalSpent: Float = 0,
        totalProfit: Float = 0,
        winRate: Float = 0,
        averageBet: Float = 0
    ) {
        self.ticketCount = ticketCount
        self.totalSpent = totalSpent
        self.totalProfit = totalProfit
        self.winRate = winRate
        self.averageBet = averageBet
    }
}

struct TypeDistribution: Identifiable {
    let id = UUID()
    let type: LotteryType
    let amount: Float
    let percentage: Float
}

struct DailyProfit: Identifiable {
    let id = UUID()
    let date: Date
    let profit: Float
}
