//
//  ScenicApplicationViewModelTests.swift
//  suixinkanTests
//

import XCTest
@testable import suixinkan

@MainActor
/// 景区申请 ViewModel 测试。
final class ScenicApplicationViewModelTests: XCTestCase {

    func testCanSubmitRequiresRequiredFields() {
        let viewModel = ScenicApplicationViewModel()
        XCTAssertFalse(viewModel.canSubmit)

        viewModel.onProvinceSelected("浙江省")
        viewModel.onCitySelected("杭州市")
        viewModel.onRemarksChange("合作备注")
        XCTAssertFalse(viewModel.canSubmit)

        viewModel.toggleAgreement()
        XCTAssertTrue(viewModel.canSubmit)
    }

    func testRemarksMaxLengthShowsMessage() {
        let viewModel = ScenicApplicationViewModel()
        var message: String?
        viewModel.onShowMessage = { message = $0 }

        let longText = String(repeating: "a", count: 51)
        viewModel.onRemarksChange(longText)

        XCTAssertEqual(viewModel.remarks.count, 0)
        XCTAssertEqual(message, "备注信息最多50字")
    }

    func testProvinceSelectionClearsCity() {
        let viewModel = ScenicApplicationViewModel()
        viewModel.onProvinceSelected("浙江省")
        viewModel.onCitySelected("杭州市")
        XCTAssertEqual(viewModel.selectedCity, "杭州市")

        viewModel.onProvinceSelected("江苏省")
        XCTAssertEqual(viewModel.selectedProvince, "江苏省")
        XCTAssertEqual(viewModel.selectedCity, "")
    }

    func testInitWithPendingApplicationStatus1() async throws {
        let pendingJSON = """
        {"code":100000,"msg":"success","data":{"items":[{"id":1,"scenic_name":"测试景区","scenic_images":"https://a.com/1.jpg,https://a.com/2.jpg","scenic_province":"浙江省","scenic_city":"杭州市","coop_type":2,"remark":"备注","status":1}]}}
        """.data(using: .utf8)!
        let areasJSON = """
        {"code":100000,"msg":"success","data":[{"id":1,"name":"浙江省","children":[{"id":2,"name":"杭州市"}]}]}
        """.data(using: .utf8)!
        let homeAPI = HomeAPI(client: APIClient(environment: .testing, session: MockURLSession(responses: [pendingJSON])))
        let profileAPI = ProfileAPI(client: APIClient(environment: .testing, session: MockURLSession(responses: [areasJSON])))
        let viewModel = ScenicApplicationViewModel()

        await viewModel.loadAreas(profileAPI: profileAPI)
        await viewModel.loadPendingApplication(homeAPI: homeAPI)

        XCTAssertEqual(viewModel.scenicName, "测试景区")
        XCTAssertEqual(viewModel.selectedProvince, "浙江省")
        XCTAssertEqual(viewModel.selectedCity, "杭州市")
        XCTAssertEqual(viewModel.selectedCooperationType, .resourceProvider)
        XCTAssertEqual(viewModel.remarks, "备注")
        XCTAssertEqual(viewModel.selectedImages.count, 2)
        XCTAssertTrue(viewModel.isReadOnly)
        XCTAssertTrue(viewModel.shouldShowAuditCard)
    }

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

        await viewModel.submit(homeAPI: api)
        XCTAssertEqual(message, "请完善必填信息")
    }

    func testSubmitSuccessCallsCallback() async throws {
        let submitJSON = """
        {"code":100000,"msg":"success","data":{}}
        """.data(using: .utf8)!
        let pendingJSON = """
        {"code":100000,"msg":"success","data":{"items":[]}}
        """.data(using: .utf8)!
        let api = HomeAPI(client: APIClient(environment: .testing, session: MockURLSession(responses: [submitJSON, pendingJSON])))
        let viewModel = ScenicApplicationViewModel()
        viewModel.onProvinceSelected("浙江省")
        viewModel.onCitySelected("杭州市")
        viewModel.onRemarksChange("合作")
        viewModel.toggleAgreement()

        var didSubmit = false
        viewModel.onSubmitSuccess = { didSubmit = true }
        var messages: [String] = []
        viewModel.onShowMessage = { messages.append($0) }

        await viewModel.submit(homeAPI: api)

        XCTAssertTrue(didSubmit)
        XCTAssertEqual(messages.first, "提交成功")
    }
}
