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

import XCTest
@testable import suixinkan

@MainActor
/// 账号上下文测试，覆盖景区、门店和角色权限的选择恢复。
final class AccountContextTests: XCTestCase {
    /// 测试 replaceScopes 能按缓存 ID 恢复当前景区和门店。
    func testReplaceScopesRestoresCurrentSelectionsById() {
        let context = AccountContext()
        let scenicScopes = [
            BusinessScope(id: 1, name: "默认景区", kind: .scenic),
            BusinessScope(id: 2, name: "缓存景区", kind: .scenic)
        ]
        let storeScopes = [
            BusinessScope(id: 10, name: "默认门店", kind: .store),
            BusinessScope(id: 20, name: "缓存门店", kind: .store)
        ]

        context.replaceScopes(
            scenic: scenicScopes,
            stores: storeScopes,
            currentScenicId: 2,
            currentStoreId: 20
        )

        XCTAssertEqual(context.currentScenic?.id, 2)
        XCTAssertEqual(context.currentStore?.id, 20)
    }

    /// 测试缓存 ID 不存在时会回退到首个可用作用域。
    func testReplaceScopesFallsBackToFirstScopeWhenCachedIdIsMissing() {
        let context = AccountContext()

        context.replaceScopes(
            scenic: [BusinessScope(id: 1, name: "默认景区", kind: .scenic)],
            stores: [BusinessScope(id: 10, name: "默认门店", kind: .store)],
            currentScenicId: 999,
            currentStoreId: 999
        )

        XCTAssertEqual(context.currentScenic?.id, 1)
        XCTAssertEqual(context.currentStore?.id, 10)
    }

    /// 测试切换景区时会优先选择同景区门店。
    func testSelectScenicResolvesStoreWithinSelectedScenic() {
        let context = AccountContext()
        context.replaceScopes(
            scenic: [
                BusinessScope(id: 1, name: "西湖景区", kind: .scenic),
                BusinessScope(id: 2, name: "东湖景区", kind: .scenic)
            ],
            stores: [
                BusinessScope(id: 10, name: "西湖门店", kind: .store, parentScenicId: 1),
                BusinessScope(id: 20, name: "东湖门店", kind: .store, parentScenicId: 2)
            ],
            currentScenicId: 1,
            currentStoreId: 10
        )

        context.selectScenic(id: 2)

        XCTAssertEqual(context.currentScenic?.id, 2)
        XCTAssertEqual(context.currentStore?.id, 20)
    }

    /// 测试切换角色时会同步角色景区并重新匹配门店。
    func testSelectRoleUpdatesScenicScopesAndStoreSelection() {
        let accountContext = AccountContext()
        let permissionContext = PermissionContext()
        accountContext.replaceScopes(
            scenic: [BusinessScope(id: 1, name: "旧景区", kind: .scenic)],
            stores: [
                BusinessScope(id: 10, name: "旧门店", kind: .store, parentScenicId: 1),
                BusinessScope(id: 20, name: "新门店", kind: .store, parentScenicId: 2)
            ],
            currentScenicId: 1,
            currentStoreId: 10
        )
        permissionContext.replaceRolePermissions([
            RolePermissionResponse(
                role: RoleInfo(id: 1, name: "旧角色"),
                scenic: [ScenicInfo(id: 1, name: "旧景区")]
            ),
            RolePermissionResponse(
                role: RoleInfo(id: 2, name: "新角色"),
                scenic: [ScenicInfo(id: 2, name: "新景区")]
            )
        ])

        permissionContext.selectRole(id: 2, accountContext: accountContext)

        XCTAssertEqual(permissionContext.currentRole?.id, 2)
        XCTAssertEqual(accountContext.scenicScopes.map(\.id), [2])
        XCTAssertEqual(accountContext.currentScenic?.id, 2)
        XCTAssertEqual(accountContext.currentStore?.id, 20)
    }

    /// 测试权限上下文会递归展开权限 URI。
    func testPermissionContextFlattensPermissionURIs() {
        let permissionContext = PermissionContext()
        permissionContext.replaceRolePermissions([
            RolePermissionResponse(
                role: RoleInfo(
                    id: 1,
                    name: "运营",
                    permission: [
                        PermissionItem(
                            id: 1,
                            name: "首页",
                            uri: "/home",
                            children: [
                                PermissionItem(id: 2, name: "订单", uri: "/orders")
                            ]
                        )
                    ]
                ),
                scenic: []
            )
        ])

        XCTAssertTrue(permissionContext.canAccess("/home"))
        XCTAssertTrue(permissionContext.canAccess("/orders"))
        XCTAssertFalse(permissionContext.canAccess("/settings"))
    }
}
