//
//  ScenicSelectionViewModelTests.swift
//  suixinkanTests
//

import XCTest
@testable import suixinkan

/// 景区选择 ViewModel 测试。
final class ScenicSelectionViewModelTests: XCTestCase {

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

    override func setUp() {
        defaults = UserDefaults(suiteName: "ScenicSelectionViewModelTests")!
        defaults.removePersistentDomain(forName: "ScenicSelectionViewModelTests")
        appStore = AppStore(defaults: defaults)
        appStore.session.configureTestAccount()
    }

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

    func testSearchFiltersByNameAndAddress() {
        appStore.permissions.saveRoleScenicList([
            ScenicInfo(id: 1, name: "西湖景区", status: 1, location: ScenicLocationInfo(lng: 120.1, lat: 30.2, address: "杭州西湖"), coverImg: nil),
            ScenicInfo(id: 2, name: "灵隐寺", status: 1, location: ScenicLocationInfo(lng: 120.2, lat: 30.3, address: "杭州灵隐"), coverImg: nil),
        ])
        let viewModel = ScenicSelectionViewModel(appStore: appStore)

        viewModel.loadFromLocal()
        XCTAssertEqual(viewModel.spots.count, 2)

        viewModel.onSearchQueryChange("西湖")
        XCTAssertEqual(viewModel.spots.count, 1)
        XCTAssertEqual(viewModel.spots.first?.name, "西湖景区")

        viewModel.onSearchQueryChange("灵隐")
        XCTAssertEqual(viewModel.spots.count, 1)
        XCTAssertEqual(viewModel.spots.first?.name, "灵隐寺")
    }

    func testNearestTagWhenLocationProvided() {
        appStore.permissions.saveRoleScenicList([
            ScenicInfo(id: 1, name: "近", status: 1, location: ScenicLocationInfo(lng: 116.40, lat: 39.91, address: "A"), coverImg: nil),
            ScenicInfo(id: 2, name: "远", status: 1, location: ScenicLocationInfo(lng: 116.50, lat: 39.95, address: "B"), coverImg: nil),
        ])
        let items = ScenicSpotDisplayMapper.buildItems(
            scenicList: appStore.permissions.roleScenicList(),
            searchQuery: "",
            currentLat: 39.9087,
            currentLng: 116.3975,
            selectedScenicId: 0
        )
        XCTAssertEqual(items.first?.openStatus, .nearest)
    }

    func testClosedStatusTag() {
        appStore.permissions.saveRoleScenicList([
            ScenicInfo(id: 1, name: "停业", status: 2, location: nil, coverImg: nil),
        ])
        let viewModel = ScenicSelectionViewModel(appStore: appStore)
        viewModel.loadFromLocal()
        XCTAssertEqual(viewModel.spots.first?.openStatus, .closed)
        XCTAssertEqual(viewModel.spots.first?.statusLabel, "暂未营业")
    }

    func testSelectSpotWritesAppStore() {
        appStore.permissions.saveRoleScenicList([
            ScenicInfo(id: 5, name: "测试景区", status: 1),
        ])
        let viewModel = ScenicSelectionViewModel(appStore: appStore)
        var completed = false
        viewModel.onSelectionComplete = { completed = true }

        viewModel.loadFromLocal()
        viewModel.selectSpot(viewModel.spots[0])

        XCTAssertEqual(appStore.session.currentScenicId, 5)
        XCTAssertEqual(appStore.session.currentScenicName, "测试景区")
        XCTAssertTrue(completed)
        XCTAssertTrue(viewModel.spots.first?.isSelected == true)
    }

    func testOnApplyNowRoutesToStatusWhenPendingReviewing() async throws {
        let pendingJSON = """
        {"code":100000,"msg":"success","data":[{"code":"AP001","role_id":1,"role_name":"摄影师","scenic_list":[],"status":1,"status_label":"审核中","created_at":"","audit_note":"","audited_at":null,"audited_by":null}]}
        """.data(using: .utf8)!
        let api = await MainActor.run {
            HomeAPI(client: APIClient(environment: .testing, session: MockURLSession(responses: [pendingJSON])))
        }
        let viewModel = ScenicSelectionViewModel(appStore: appStore)
        var statusCode: String?
        viewModel.onNavigateApplyStatus = { statusCode = $0 }

        await viewModel.onApplyNow(api: api)

        XCTAssertEqual(statusCode, "AP001")
    }
}
