//
//  PaymentCollectionDetailsViewModelTests.swift
//  suixinkanTests
//

import XCTest
@testable import suixinkan

/// 收款详情 ViewModel 测试。
@MainActor
final class PaymentCollectionDetailsViewModelTests: XCTestCase {

    private var appStore: AppStore!

    override func setUp() {
        let defaults = UserDefaults(suiteName: "PaymentCollectionDetailsViewModelTests")!
        defaults.removePersistentDomain(forName: "PaymentCollectionDetailsViewModelTests")
        appStore = AppStore(defaults: defaults)
        appStore.userId = "10001"
        appStore.currentScenicId = 10
        appStore.currentScenicName = "测试景区"
    }

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

    func testPaymentAmountValidatorRejectsEmptyAmount() {
        XCTAssertEqual(PaymentAmountValidator.validationMessage(for: ""), "请输入收款金额")
    }

    func testPaymentAmountValidatorRejectsZeroAmount() {
        XCTAssertEqual(PaymentAmountValidator.validationMessage(for: "0"), "请输入有效的收款金额")
    }

    func testPaymentAmountValidatorRejectsMoreThanTwoDecimals() {
        XCTAssertEqual(PaymentAmountValidator.validationMessage(for: "1.234"), "金额最多支持两位小数")
    }

    func testPaymentAmountValidatorAcceptsValidAmount() {
        XCTAssertNil(PaymentAmountValidator.validationMessage(for: "12.50"))
    }

    func testShowSetAmountDialogRequiresPayCode() {
        let viewModel = PaymentCollectionDetailsViewModel(appStore: appStore)
        var message: String?
        viewModel.onShowMessage = { message = $0 }

        viewModel.showSetAmountDialog()

        XCTAssertEqual(message, "请先获取收款码")
        XCTAssertFalse(viewModel.showAmountDialog)
    }

    func testConfirmAmountBuildsDynamicURL() async throws {
        let payCodeJSON = """
        {"code":100000,"msg":"success","data":{"static_pay_url":"https://pay.example.com/static","dynamic_pay_url":"https://pay.example.com/dynamic"}}
        """.data(using: .utf8)!
        let session = MockURLSession(responses: [payCodeJSON])
        let api = PaymentAPI(client: APIClient(environment: .testing, session: session))
        let viewModel = PaymentCollectionDetailsViewModel(appStore: appStore)

        await viewModel.loadPayCode(api: api)
        viewModel.updateAmount("88.50")
        viewModel.updateRemark("测试备注")
        viewModel.confirmAmount()

        XCTAssertTrue(viewModel.hasPayCode)
        XCTAssertFalse(viewModel.showAmountDialog)
    }

    func testToggleReceiveVoicePersistsInAppStore() {
        let viewModel = PaymentCollectionDetailsViewModel(appStore: appStore)
        viewModel.refreshLocalState()

        XCTAssertFalse(viewModel.isVoiceBroadcastOpen)
        viewModel.toggleReceiveVoice()
        XCTAssertTrue(appStore.isOpenReceiveVoice)
        XCTAssertTrue(viewModel.isVoiceBroadcastOpen)
    }

    func testLoadPayCodeClearsQRWhenScenicMissing() async {
        appStore.currentScenicId = 0
        let session = MockURLSession(responses: [])
        let api = PaymentAPI(client: APIClient(environment: .testing, session: session))
        let viewModel = PaymentCollectionDetailsViewModel(appStore: appStore)

        await viewModel.loadPayCode(api: api)

        XCTAssertFalse(viewModel.hasPayCode)
        XCTAssertEqual(session.requests.count, 0)
    }
}
