//
//  CooperationAcquirerViewModelTests.swift
//  suixinkanTests
//

import XCTest
@testable import suixinkan

@MainActor
final class CooperationAcquirerViewModelTests: XCTestCase {

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

    override func setUp() {
        defaults = UserDefaults(suiteName: "CooperationAcquirerViewModelTests")!
        defaults.removePersistentDomain(forName: "CooperationAcquirerViewModelTests")
        appStore = AppStore(defaults: defaults)
        appStore.session.configureTestAccount(accountType: .storeUser, scenicId: 10)
        appStore.session.currentStoreId = 5
    }

    func testSaveRemarkWithValidLengthCallsAPI() async throws {
        let json = """
        {"code":100000,"msg":"success","data":{}}
        """.data(using: .utf8)!
        let viewModel = CooperationAcquirerViewModel(appStore: appStore)
        var message: String?
        viewModel.onShowMessage = { message = $0 }
        viewModel.startEditRemark(CooperativeSalerEntity(saleUserId: 1))
        viewModel.updateRemarkDraft("备注A")

        await viewModel.saveRemark(api: makeAPI(responses: [json]))

        XCTAssertEqual(message, "备注已保存")
    }

    func testSaveCommissionRateRequiresSmsCode() async {
        let viewModel = CooperationAcquirerViewModel(appStore: appStore)
        var message: String?
        viewModel.onShowMessage = { message = $0 }
        viewModel.startEditCommissionRate(CooperativeSalerEntity(saleUserId: 1, salerPhone: "13800138000"))
        viewModel.updateCommissionRateDraft("20")

        await viewModel.saveCommissionRate(api: makeAPI(responses: []))

        XCTAssertEqual(message, "请输入验证码")
    }

    func testCommissionRateDraftFiltersDigitsAndLimitsLength() {
        let viewModel = CooperationAcquirerViewModel(appStore: appStore)

        viewModel.updateCommissionRateDraft("a12b345")

        XCTAssertEqual(viewModel.commissionRateDraft, "123")
    }

    func testCommissionSmsCodeDraftFiltersDigitsAndLimitsLength() {
        let viewModel = CooperationAcquirerViewModel(appStore: appStore)

        viewModel.updateCommissionSmsCodeDraft("1a2b345678")

        XCTAssertEqual(viewModel.commissionSmsCodeDraft, "123456")
    }

    func testRequestCommissionSmsCodeShowsCountdownMessageWhenTimerActive() async {
        let json = """
        {"code":100000,"msg":"success","data":{}}
        """.data(using: .utf8)!
        let viewModel = CooperationAcquirerViewModel(appStore: appStore)
        var message: String?
        viewModel.onShowMessage = { message = $0 }
        viewModel.startEditCommissionRate(CooperativeSalerEntity(saleUserId: 1, salerPhone: "13800138000"))

        await viewModel.requestCommissionSmsCode(api: makeAPI(responses: [json]))
        await Task.yield()
        await viewModel.requestCommissionSmsCode(api: makeAPI(responses: []))

        XCTAssertEqual(message, "请在倒计时结束后重新获取")
        viewModel.dismissCommissionRateDialog()
    }

    func testProcessScanResultNavigatesWithValidQR() {
        let viewModel = CooperationAcquirerViewModel(appStore: appStore)
        var navigatedId: Int?
        viewModel.onNavigateBindAcquirer = { navigatedId = $0 }

        viewModel.processScanResult(#"{"method":"sale_user_bind","sale_user_id":88}"#)

        XCTAssertEqual(navigatedId, 88)
    }

    func testProcessScanResultShowsErrorForInvalidQR() {
        let viewModel = CooperationAcquirerViewModel(appStore: appStore)
        var message: String?
        viewModel.onNavigateBindAcquirer = { _ in XCTFail("Should not navigate") }
        viewModel.onShowMessage = { message = $0 }

        viewModel.processScanResult("invalid")

        XCTAssertEqual(message, "请扫描正确的获客员二维码")
    }

    func testLoadAcquirersUsesStoreId() async throws {
        let json = """
        {"code":100000,"msg":"success","data":{"total":1,"list":[{"sale_user_id":3,"name":"获客员A"}]}}
        """.data(using: .utf8)!
        let session = MockURLSession(responses: [json])
        let api = OrderAPI(client: APIClient(environment: .testing, session: session))
        let viewModel = CooperationAcquirerViewModel(appStore: appStore)

        await viewModel.loadAcquirers(api: api)

        XCTAssertEqual(viewModel.acquirers.count, 1)
        let url = try XCTUnwrap(session.requests.first?.url?.absoluteString)
        XCTAssertTrue(url.contains("store_id=5"))
    }

    private func makeAPI(responses: [Data]) -> OrderAPI {
        OrderAPI(client: APIClient(environment: .testing, session: MockURLSession(responses: responses)))
    }
}
