//
//  StatisticsViewModel.swift
//  suixinkan
//
//  Created by Codex on 2026/6/22.
//

import Foundation
import Observation

@MainActor
@Observable
/// 数据统计页面 ViewModel，管理时间段、汇总数据、每日明细和分页状态。
final class StatisticsViewModel {
    var selectedPeriod: StatisticsPeriod = .today
    private(set) var loading = false
    private(set) var loadingMore = false
    private(set) var summary = StatisticsSummaryResponse()
    private(set) var dailyItems: [StatisticsDailyItem] = []
    private(set) var totalDailyCount = 0
    private(set) var lastRefreshAt: Date?

    private var page = 1
    private let pageSize = 15

    /// 当前日数据是否还有下一页。
    var hasMore: Bool {
        dailyItems.count < totalDailyCount
    }

    /// 切换统计时间段，并重置分页重新加载。
    func selectPeriod(_ period: StatisticsPeriod, api: StatisticsServing, scenicId: Int?, roleId: Int?) async throws {
        selectedPeriod = period
        try await reload(api: api, scenicId: scenicId, roleId: roleId)
    }

    /// 刷新统计汇总和第一页日数据，缺少景区时清空旧状态。
    func reload(api: StatisticsServing, scenicId: Int?, roleId: Int?, showLoading: Bool = true) async throws {
        guard let scenicId else {
            reset()
            return
        }

        if showLoading { loading = true }
        defer { if showLoading { loading = false } }

        let isScenicAdmin = roleId == 53
        async let summaryResult = api.summary(
            scenicId: scenicId,
            range: selectedPeriod.apiRange,
            isScenicAdmin: isScenicAdmin
        )
        async let dailyResult = api.dailyList(
            scenicId: scenicId,
            startTime: selectedPeriod.apiStartTime,
            endTime: selectedPeriod.apiEndTime,
            page: 1,
            pageSize: pageSize,
            isScenicAdmin: isScenicAdmin
        )
        let (summaryData, dailyData) = try await (summaryResult, dailyResult)
        summary = summaryData
        dailyItems = dailyData.data
        totalDailyCount = dailyData.total
        page = 1
        lastRefreshAt = Date()
    }

    /// 加载每日统计下一页。
    func loadMore(api: StatisticsServing, scenicId: Int?, roleId: Int?) async throws {
        guard !loadingMore, hasMore, let scenicId else { return }

        loadingMore = true
        defer { loadingMore = false }

        let nextPage = page + 1
        let result = try await api.dailyList(
            scenicId: scenicId,
            startTime: selectedPeriod.apiStartTime,
            endTime: selectedPeriod.apiEndTime,
            page: nextPage,
            pageSize: pageSize,
            isScenicAdmin: roleId == 53
        )
        dailyItems.append(contentsOf: result.data)
        totalDailyCount = result.total
        page = nextPage
    }

    /// 清空统计状态。
    private func reset() {
        summary = StatisticsSummaryResponse()
        dailyItems = []
        totalDailyCount = 0
        page = 1
        lastRefreshAt = nil
        loading = false
        loadingMore = false
    }
}
