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

import Foundation
import Observation

@MainActor
@Observable
/// 账号切换 ViewModel，管理可切换账号列表、选择状态和提交状态。
final class AccountSwitchViewModel {
    private(set) var accounts: [AccountSwitchAccount] = []
    var selectedAccountId: String?
    private(set) var loading = false
    private(set) var switching = false
    private var didLoad = false

    /// 当前选中的账号。
    var selectedAccount: AccountSwitchAccount? {
        accounts.first { $0.id == selectedAccountId }
    }

    /// 拉取可切换账号列表，默认只加载一次。
    func load(api: ProfileAPI, force: Bool = false, currentAccountId: String? = nil) async throws {
        guard force || !didLoad else { return }
        didLoad = true
        loading = true
        defer { loading = false }

        let response = try await api.switchableAccounts()
        accounts = response.accounts.filter { $0.businessUserId > 0 }
        selectedAccountId = accounts.first(where: { $0.isCurrent || isCurrent($0, currentAccountId: currentAccountId) })?.id
            ?? accounts.first?.id
    }

    /// 选择指定账号。
    func select(_ account: AccountSwitchAccount) {
        selectedAccountId = account.id
    }

    /// 提交账号切换，调用 set-user 换取正式 token。
    func switchAccount(_ account: AccountSwitchAccount, api: AuthAPI) async throws -> V9AuthResponse {
        guard !switching else {
            throw AccountSwitchError.submitting
        }
        guard account.businessUserId > 0 else {
            throw AccountSwitchError.invalidAccount
        }

        switching = true
        defer { switching = false }
        return try await api.setUser(account.toSetUserRequest())
    }

    /// 判断账号是否与当前账号标识一致。
    func isCurrent(_ account: AccountSwitchAccount, currentAccountId: String?) -> Bool {
        guard let currentAccountId else { return false }
        return account.id == currentAccountId || String(account.businessUserId) == currentAccountId
    }
}

/// 账号切换错误实体，表示重复提交或账号数据异常。
enum AccountSwitchError: LocalizedError, Equatable {
    case submitting
    case invalidAccount

    var errorDescription: String? {
        switch self {
        case .submitting:
            "账号正在切换，请稍候"
        case .invalidAccount:
            "账号信息异常，请重新选择账号"
        }
    }
}
