//
//  AuthModelsTests.swift
//  suixinkanTests
//
//  Created by Codex on 2026/6/26.
//

import XCTest
@testable import suixinkan

/// Auth 模块模型测试，覆盖 v9 登录响应解码和账号转换规则。
final class AuthModelsTests: XCTestCase {
    /// 测试多账号登录 fixture 能正确解码并合并景区、门店账号。
    func testV9AuthResponseDecodesMultiAccountFixture() throws {
        let response = try TestFixture.payload(V9AuthResponse.self, named: "v9_login_multi_success")

        XCTAssertEqual(response.token, "person-temp-token")
        XCTAssertEqual(response.scenicUsers.count, 1)
        XCTAssertEqual(response.storeUsers.count, 1)
        XCTAssertEqual(response.accounts.map(\.businessUserId), [101, 201])
    }

    /// 测试景区账号会优先使用 ss_user_id 作为业务账号 ID。
    func testV9ScenicUserBusinessUserIdPrefersSsUserId() throws {
        let json = """
        {
          "account_type": "scenic_user",
          "id": 1,
          "user_id": 2,
          "scenic_user_id": 3,
          "ss_user_id": 101,
          "username": "scenic_admin",
          "real_name": "张三",
          "nickname": "张三",
          "phone": "13800138000",
          "scenic_id": 10,
          "scenic_name": "示例景区",
          "is_current": false
        }
        """.data(using: .utf8)!
        let user = try JSONDecoder().decode(V9ScenicUser.self, from: json)

        XCTAssertEqual(user.businessUserId, 101)
        XCTAssertEqual(user.toAccountSwitchAccount().accountType, V9ScenicUser.accountTypeValue)
        XCTAssertEqual(user.toAccountSwitchAccount().toSetUserRequest(), SetUserRequest(ssUserId: 101))
    }

    /// 测试门店账号会优先使用 store_user_id 作为业务账号 ID。
    func testV9StoreUserBusinessUserIdPrefersStoreUserId() throws {
        let json = """
        {
          "account_type": "store_user",
          "id": 1,
          "user_id": 2,
          "store_user_id": 201,
          "username": "store_admin",
          "user_name": "store_admin",
          "real_name": "张三",
          "phone": "13800138000",
          "avatar": "",
          "scenic_id": 10,
          "scenic_name": "示例景区",
          "store_id": 20,
          "store_name": "示例门店",
          "is_current": false
        }
        """.data(using: .utf8)!
        let user = try JSONDecoder().decode(V9StoreUser.self, from: json)

        XCTAssertEqual(user.businessUserId, 201)
        XCTAssertEqual(user.toAccountSwitchAccount().accountType, V9StoreUser.accountTypeValue)
        XCTAssertEqual(user.toAccountSwitchAccount().toSetUserRequest(), SetUserRequest(storeUserId: 201))
    }

    /// 测试登录响应会派生景区和门店作用域，并去重。
    func testV9AuthResponseDerivesScopesFromAccounts() throws {
        let response = try TestFixture.payload(V9AuthResponse.self, named: "v9_login_multi_success")

        XCTAssertEqual(response.scenicScopes.map(\.id), [10])
        XCTAssertEqual(response.storeScopes.map(\.id), [20])
        XCTAssertEqual(response.primaryProfile?.displayName, "示例门店")
    }

    /// 测试 LoginRequest 会填充后端要求的默认字段。
    func testLoginRequestEncodesExpectedDefaults() throws {
        let request = LoginRequest(username: "18651857230", password: "secret123")
        let json = try JSONSerialization.jsonObject(with: JSONEncoder().encode(request)) as? [String: Any]

        XCTAssertEqual(json?["username"] as? String, "18651857230")
        XCTAssertEqual(json?["password"] as? String, "secret123")
        XCTAssertEqual(json?["type"] as? Int, 1)
        XCTAssertEqual(json?["mobile"] as? String, "")
        XCTAssertEqual(json?["code"] as? String, "")
    }
}
