//
//  SettingViewModel.swift
//  suixinkan
//

import Foundation

/// 设置中心 ViewModel，管理版本展示、协议入口和更新标记。
final class SettingViewModel {
    private let infoDictionary: [String: Any]?
    private let environment: APIEnvironment

    private(set) var latestVersion: VersionResponse?
    private(set) var hasNewVersion = false

    var onStateChange: (() -> Void)?

    init(
        infoDictionary: [String: Any]? = Bundle.main.infoDictionary,
        environment: APIEnvironment = .current
    ) {
        self.infoDictionary = infoDictionary
        self.environment = environment
    }

    var appVersion: String {
        AppClientInfo.appVersion(infoDictionary: infoDictionary)
    }

    var appDownloadURL: URL {
        environment.baseURL.appending(path: "h5/app/download")
    }

    /// 静默检查最新版本，失败时保持当前页面状态。
    func checkLatestVersion(api: SettingAPI) async {
        do {
            let response = try await api.checkLatestVersion()
            latestVersion = response
            hasNewVersion = Self.isNewerVersionCode(response.versionCode, than: currentVersionCode(infoDictionary: infoDictionary))
            notifyStateChange()
        } catch is CancellationError {
            return
        } catch {
            latestVersion = nil
            hasNewVersion = false
            notifyStateChange()
        }
    }

    /// 返回指定协议入口的标题和 URL。
    func agreementDestination(for kind: SettingAgreementKind) -> SettingAgreementDestination {
        switch kind {
        case .aboutUs:
            SettingAgreementDestination(
                title: "关于我们",
                url: environment.baseURL.appending(path: "h5/app/about-us")
            )
        case .userAgreement:
            SettingAgreementDestination(
                title: "用户协议",
                url: environment.baseURL.appending(path: "h5/app/user-agreement")
            )
        case .privacyPolicy:
            SettingAgreementDestination(
                title: "隐私政策",
                url: environment.baseURL.appending(path: "h5/app/privacy-policy")
            )
        }
    }

    /// 判断后端版本号是否高于当前构建号。
    nonisolated static func isNewerVersionCode(_ latestVersionCode: Int, than currentVersionCode: Int?) -> Bool {
        guard let currentVersionCode else { return false }
        return latestVersionCode > currentVersionCode
    }

    private func currentVersionCode(infoDictionary: [String: Any]?) -> Int? {
        let build = (infoDictionary?["CFBundleVersion"] as? String)?
            .trimmingCharacters(in: .whitespacesAndNewlines)
        guard let build, !build.isEmpty else { return nil }
        return Int(build)
    }

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