//
//  PermissionApplyViewModelTests.swift
//  suixinkanTests
//

import XCTest
@testable import suixinkan

@MainActor
/// 权限申请 ViewModel 测试。
final class PermissionApplyViewModelTests: XCTestCase {

    private var appStore: AppStore!
    private var defaults: UserDefaults!

    override func setUp() {
        defaults = UserDefaults(suiteName: "PermissionApplyViewModelTests")!
        defaults.removePersistentDomain(forName: "PermissionApplyViewModelTests")
        appStore = AppStore(defaults: defaults)
        appStore.saveRolePermissionList([
            RolePermissionResponse(
                role: RoleInfo(id: 10, name: "摄影师", roleCode: "PHOTOGRAPHER", notes: "拍摄"),
                scenic: [ScenicInfo(id: 100, name: "已有景区", status: 1)]
            ),
        ])
    }

    override func tearDown() {
        appStore.logout()
        super.tearDown()
    }

    func testExistingScenicIsDisabledAfterLoad() async throws {
        let scenicJSON = """
        {"code":100000,"msg":"success","data":{"total":2,"list":[{"id":100,"name":"已有景区"},{"id":101,"name":"新景区"}]}}
        """.data(using: .utf8)!
        let api = HomeAPI(client: APIClient(environment: .testing, session: MockURLSession(responses: [scenicJSON])))
        let viewModel = PermissionApplyViewModel(appStore: appStore)
        viewModel.selectRole(RoleOption(id: 10, name: "摄影师", description: "拍摄", isSelected: true))

        await viewModel.loadAvailableScenics(api: api)

        let existing = viewModel.availableScenics.first { $0.id == 100 }
        let fresh = viewModel.availableScenics.first { $0.id == 101 }
        XCTAssertEqual(existing?.isDisabled, true)
        XCTAssertEqual(existing?.isSelected, true)
        XCTAssertEqual(fresh?.isDisabled, false)
    }

    func testSubmitValidationRequiresRoleAndScenic() async {
        let api = HomeAPI(client: APIClient(environment: .testing, session: MockURLSession(responses: [])))
        let viewModel = PermissionApplyViewModel(appStore: appStore)
        var message: String?
        viewModel.onShowMessage = { message = $0 }

        await viewModel.submit(api: api)
        XCTAssertEqual(message, "请选择角色")

        viewModel.selectRole(RoleOption(id: 10, name: "摄影师", description: "", isSelected: true))
        await viewModel.submit(api: api)
        XCTAssertEqual(message, "请至少选择一个景区")
    }

    func testSubmitSuccessReturnsApplyCode() async throws {
        let scenicJSON = """
        {"code":100000,"msg":"success","data":{"total":1,"list":[{"id":101,"name":"新景区"}]}}
        """.data(using: .utf8)!
        let submitJSON = """
        {"code":100000,"msg":"success","data":{"code":"AP999"}}
        """.data(using: .utf8)!
        let api = HomeAPI(client: APIClient(environment: .testing, session: MockURLSession(responses: [scenicJSON, submitJSON])))
        let viewModel = PermissionApplyViewModel(appStore: appStore)
        viewModel.selectRole(RoleOption(id: 10, name: "摄影师", description: "", isSelected: true))
        await viewModel.loadAvailableScenics(api: api)
        if let scenic = viewModel.availableScenics.first(where: { $0.id == 101 }) {
            viewModel.toggleScenic(scenic)
        }

        var applyCode: String?
        viewModel.onSubmitSuccess = { applyCode = $0 }
        await viewModel.submit(api: api)

        XCTAssertEqual(applyCode, "AP999")
    }
}
