//
//  ScenicQueueSettingChangeLogViewModel.swift
//  suixinkan
//

import Foundation

/// 排队设置配置日志 ViewModel。
final class ScenicQueueSettingChangeLogViewModel {
    private enum Constants {
        static let pageSize = 20
    }

    private(set) var items: [ScenicQueueSettingChangeLogItem] = []
    private(set) var isRefreshing = false
    private(set) var isLoadingMore = false
    private(set) var canLoadMore = false
    private(set) var initialLoading = true

    var onStateChange: (() -> Void)?
    var onShowMessage: ((String) -> Void)?

    private let appStore: AppStore
    private var total = 0
    private var lastLoadedPage = 0

    init(appStore: AppStore = .shared) {
        self.appStore = appStore
    }

    /// 刷新配置日志。
    func refresh(api: ScenicQueueAPIProtocol) async {
        await load(api: api, page: 1, append: false)
    }

    /// 加载更多配置日志。
    func loadMore(api: ScenicQueueAPIProtocol) async {
        guard canLoadMore, !isRefreshing, !isLoadingMore else { return }
        await load(api: api, page: lastLoadedPage + 1, append: true)
    }

    private func load(api: ScenicQueueAPIProtocol, page: Int, append: Bool) async {
        guard appStore.session.currentScenicId > 0 else {
            onShowMessage?("请先选择景区")
            return
        }
        if append {
            isLoadingMore = true
        } else {
            isRefreshing = true
        }
        notifyStateChange()
        defer {
            initialLoading = false
            if append { isLoadingMore = false } else { isRefreshing = false }
            notifyStateChange()
        }
        let spotId = Int64(appStore.scenicQueue.punchSpotId)
        do {
            let data = try await api.settingChangeLog(
                scenicId: Int64(appStore.session.currentScenicId),
                scenicSpotId: spotId,
                page: page,
                pageSize: Constants.pageSize
            )
            if append {
                let seen = Set(items.map(\.id))
                items += data.list.filter { !seen.contains($0.id) }
            } else {
                items = data.list
            }
            total = max(0, data.total)
            lastLoadedPage = max(1, data.page)
            canLoadMore = items.count < total && !data.list.isEmpty
        } catch {
            onShowMessage?(error.localizedDescription)
        }
    }

    private func notifyStateChange() {
        onStateChange?()
    }
}
