//
//  StorageTests.swift
//  suixinkanTests
//
//  Created by Codex on 2026/6/20.
//

import XCTest
@testable import suixinkan

/// 本地缓存 Store 测试，覆盖 UserDefaults 中的偏好和账号快照。
final class StorageTests: XCTestCase {
    /// 测试 SessionTokenStore 使用 UserDefaults 保存、读取、修剪和清空正式 token。
    func testSessionTokenStorePersistsTokenInUserDefaults() throws {
        let defaults = makeIsolatedDefaults()
        let store = SessionTokenStore(defaults: defaults, key: "session.token.test")

        try store.save("  token-123  ")
        XCTAssertEqual(store.load(), "token-123")

        try store.clear()
        XCTAssertNil(store.load())
    }

    /// 测试保存空 token 会清空本地正式 token。
    func testSessionTokenStoreClearsWhenSavingBlankToken() throws {
        let defaults = makeIsolatedDefaults()
        let store = SessionTokenStore(defaults: defaults, key: "session.token.blank.test")

        try store.save("token-123")
        try store.save("   \n")

        XCTAssertNil(store.load())
    }

    /// 测试 AppPreferencesStore 能保存并读取上次登录手机号和协议状态。
    func testAppPreferencesStorePersistsLoginPreferences() {
        let defaults = makeIsolatedDefaults()
        let store = AppPreferencesStore(defaults: defaults)

        store.saveLastLoginUsername(" 18651857230 ")
        store.savePrivacyAgreementAccepted(true)

        XCTAssertEqual(store.loadLastLoginUsername(), "18651857230")
        XCTAssertTrue(store.loadPrivacyAgreementAccepted())
    }

    /// 测试清空登录页偏好会移除隐私协议同意状态。
    func testAppPreferencesStoreClearRemovesPrivacyAgreement() {
        let defaults = makeIsolatedDefaults()
        let store = AppPreferencesStore(defaults: defaults)

        store.savePrivacyAgreementAccepted(true)
        store.clear()

        XCTAssertFalse(store.loadPrivacyAgreementAccepted())
    }

    /// 测试登录协调器保存隐私同意状态后会触发回调。
    @MainActor
    func testAuthSessionCoordinatorPrivacyPersistenceTriggersCallback() {
        let defaults = makeIsolatedDefaults()
        let store = AppPreferencesStore(defaults: defaults)
        var persistedValues: [Bool] = []
        let coordinator = AuthSessionCoordinator(
            tokenStore: SessionTokenStore(defaults: defaults, key: "session.token.privacy.test"),
            snapshotStore: AccountSnapshotStore(defaults: defaults, key: "account.snapshot.privacy.test"),
            preferencesStore: store,
            onPrivacyAgreementPersisted: { persistedValues.append($0) }
        )

        coordinator.savePrivacyAgreementAccepted(true)

        XCTAssertTrue(store.loadPrivacyAgreementAccepted())
        XCTAssertEqual(persistedValues, [true])
    }

    /// 测试退出登录会保留隐私协议状态等非敏感偏好。
    @MainActor
    func testAuthSessionCoordinatorLogoutKeepsPrivacyAgreement() {
        let defaults = makeIsolatedDefaults()
        let store = AppPreferencesStore(defaults: defaults)
        let coordinator = AuthSessionCoordinator(
            tokenStore: SessionTokenStore(defaults: defaults, key: "session.token.logout.test"),
            snapshotStore: AccountSnapshotStore(defaults: defaults, key: "account.snapshot.logout.test"),
            preferencesStore: store
        )
        coordinator.savePrivacyAgreementAccepted(true)

        coordinator.logout(
            appSession: AppSession(),
            accountContext: AccountContext(),
            permissionContext: PermissionContext(),
            scenicSpotContext: ScenicSpotContext(),
            appRouter: AppRouter(),
            toastCenter: ToastCenter()
        )

        XCTAssertTrue(store.loadPrivacyAgreementAccepted())
    }

    /// 测试账号快照能保存并恢复账号资料、业务作用域和当前选择。
    func testAccountSnapshotStorePersistsAccountContextSnapshot() {
        let defaults = makeIsolatedDefaults()
        let store = AccountSnapshotStore(defaults: defaults)
        let snapshot = AccountSnapshot(
            profile: AccountProfile(
                userId: "101",
                displayName: "测试账号",
                phone: "18651857230",
                avatarURL: "https://cdn.example.com/avatar.jpg"
            ),
            accountType: "store_user",
            businessUserId: 101,
            scenicScopes: [
                BusinessScope(id: 88, name: "东门景区", kind: .scenic)
            ],
            storeScopes: [
                BusinessScope(id: 66, name: "东门门店", kind: .store)
            ],
            currentScenicId: 88,
            currentStoreId: 66
        )

        store.save(snapshot)

        XCTAssertEqual(store.load(), snapshot)
    }

    /// 创建独立 UserDefaults，避免测试污染真实 App 偏好。
    private func makeIsolatedDefaults() -> UserDefaults {
        let suiteName = "suixinkan.tests.\(UUID().uuidString)"
        let defaults = UserDefaults(suiteName: suiteName)!
        defaults.removePersistentDomain(forName: suiteName)
        return defaults
    }
}
