//
//  AccountSnapshotStore.swift
//  suixinkan
//
//  Created by Codex on 2026/6/20.
//

import Foundation
import Observation

/// 账号缓存快照实体，保存可重建、非敏感的账号展示和业务上下文。
struct AccountSnapshot: Codable, Equatable {
    var profile: AccountProfile?
    var accountType: String?
    var businessUserId: Int?
    var currentRoleId: Int?
    var scenicScopes: [BusinessScope]
    var storeScopes: [BusinessScope]
    var currentScenicId: Int?
    var currentStoreId: Int?

    /// 创建账号缓存快照，默认没有业务作用域。
    init(
        profile: AccountProfile? = nil,
        accountType: String? = nil,
        businessUserId: Int? = nil,
        currentRoleId: Int? = nil,
        scenicScopes: [BusinessScope] = [],
        storeScopes: [BusinessScope] = [],
        currentScenicId: Int? = nil,
        currentStoreId: Int? = nil
    ) {
        self.profile = profile
        self.accountType = accountType
        self.businessUserId = businessUserId
        self.currentRoleId = currentRoleId
        self.scenicScopes = scenicScopes
        self.storeScopes = storeScopes
        self.currentScenicId = currentScenicId
        self.currentStoreId = currentStoreId
    }
}

@Observable
/// 账号快照存储服务，使用 UserDefaults 保存非敏感登录上下文。
final class AccountSnapshotStore {
    @ObservationIgnored private let defaults: UserDefaults
    @ObservationIgnored private let key: String
    @ObservationIgnored private let encoder: JSONEncoder
    @ObservationIgnored private let decoder: JSONDecoder

    /// 初始化账号快照存储服务，并允许测试注入独立的 UserDefaults。
    init(
        defaults: UserDefaults = .standard,
        key: String = "suixinkan.account.snapshot.v1",
        encoder: JSONEncoder = JSONEncoder(),
        decoder: JSONDecoder = JSONDecoder()
    ) {
        self.defaults = defaults
        self.key = key
        self.encoder = encoder
        self.decoder = decoder
    }

    /// 保存账号快照，编码失败时保持原缓存不变。
    func save(_ snapshot: AccountSnapshot) {
        guard let data = try? encoder.encode(snapshot) else { return }
        defaults.set(data, forKey: key)
    }

    /// 读取账号快照，解码失败时清空损坏数据。
    func load() -> AccountSnapshot? {
        guard let data = defaults.data(forKey: key) else { return nil }
        do {
            return try decoder.decode(AccountSnapshot.self, from: data)
        } catch {
            clear()
            return nil
        }
    }

    /// 清空账号快照缓存。
    func clear() {
        defaults.removeObject(forKey: key)
    }

    /// 仅更新当前业务选择，保留账号资料、账号类型和可选作用域等其他快照内容。
    @MainActor
    func saveCurrentSelection(
        accountContext: AccountContext,
        currentRoleId: Int?
    ) {
        let existing = load()
        save(
            AccountSnapshot(
                profile: accountContext.profile ?? existing?.profile,
                accountType: existing?.accountType,
                businessUserId: existing?.businessUserId,
                currentRoleId: currentRoleId ?? existing?.currentRoleId,
                scenicScopes: accountContext.scenicScopes,
                storeScopes: accountContext.storeScopes,
                currentScenicId: accountContext.currentScenic?.id,
                currentStoreId: accountContext.currentStore?.id
            )
        )
    }
}
