//
//  AppPermissionStore.swift
//  suixinkan
//

import Foundation

/// 管理当前账号的角色权限、首页权限与可选景区缓存。
final class AppPermissionStore {

    private enum Key: String, CaseIterable {
        case legacyRoleId = "key_in_role_id"
        case rolePermissionList = "key_role_permission_list"
        case permissionItems = "key_in_permission"
        case roleScenicList = "key_current_role_scenic_list"
    }

    private let defaults: UserDefaults
    private let session: AppSessionStore

    /// 使用指定持久化容器和会话创建权限存储。
    init(defaults: UserDefaults, session: AppSessionStore) {
        self.defaults = defaults
        self.session = session
    }

    /// 旧版 role_id，用于权限匹配兜底。
    var legacyRoleId: Int {
        get {
            guard let key = scopedKey(.legacyRoleId) else { return 0 }
            return defaults.integer(forKey: key)
        }
        set {
            guard let key = scopedKey(.legacyRoleId) else { return }
            defaults.set(newValue, forKey: key)
        }
    }

    /// 保存完整 role-permission 列表。
    func saveRolePermissionList(_ list: [RolePermissionResponse]) {
        save(list, for: .rolePermissionList)
    }

    /// 读取完整 role-permission 列表。
    func rolePermissionList() -> [RolePermissionResponse] {
        load([RolePermissionResponse].self, for: .rolePermissionList) ?? []
    }

    /// 保存当前角色扁平权限。
    func savePermissionItems(_ items: [HomePermissionItem]) {
        save(items, for: .permissionItems)
    }

    /// 读取当前角色扁平权限。
    func permissionItems() -> [HomePermissionItem] {
        load([HomePermissionItem].self, for: .permissionItems) ?? []
    }

    /// 保存当前角色可选景区列表。
    func saveRoleScenicList(_ scenicList: [ScenicInfo]) {
        save(scenicList, for: .roleScenicList)
    }

    /// 读取当前角色可选景区列表。
    func roleScenicList() -> [ScenicInfo] {
        load([ScenicInfo].self, for: .roleScenicList) ?? []
    }

    /// 在 role-permission 列表中匹配当前账号角色。
    func matchRolePermissionItem(in list: [RolePermissionResponse]) -> RolePermissionResponse? {
        RolePermissionMatcher.match(
            in: list,
            roleCode: session.roleCode,
            roleName: session.roleName,
            legacyRoleId: legacyRoleId
        )
    }

    /// 清除当前账号的全部权限缓存。
    func clear(accountScope: String) {
        guard !accountScope.isEmpty else { return }
        Key.allCases.forEach { defaults.removeObject(forKey: "\(accountScope)_\($0.rawValue)") }
    }

    private func save<Value: Encodable>(_ value: Value, for key: Key) {
        guard let scopedKey = scopedKey(key),
              let data = try? JSONEncoder().encode(value) else { return }
        defaults.set(data, forKey: scopedKey)
    }

    private func load<Value: Decodable>(_ type: Value.Type, for key: Key) -> Value? {
        guard let scopedKey = scopedKey(key),
              let data = defaults.data(forKey: scopedKey) else { return nil }
        return try? JSONDecoder().decode(type, from: data)
    }

    private func scopedKey(_ key: Key) -> String? {
        session.accountScopedKey(key.rawValue)
    }
}
