//
//  ScenicSelectionViewModel.swift
//  suixinkan
//

import Foundation

/// 权限申请审核中状态，对齐 Android role-apply pending status。
enum PermissionApplyPendingStatus {
    static let reviewing = 1
    static let rejected = 3
}

/// 景区选择 ViewModel，对齐 Android `ScenicSelectionViewModel`。
final class ScenicSelectionViewModel {

    private(set) var spots: [ScenicSpotDisplayItem] = []
    private(set) var searchQuery = ""
    private(set) var currentLocationText = "最近的景区"
    private(set) var isLocating = false
    private(set) var isLoading = false

    var onStateChange: (() -> Void)?
    var onShowMessage: ((String) -> Void)?
    var onSelectionComplete: (() -> Void)?
    var onNavigateApply: (() -> Void)?
    var onNavigateApplyStatus: ((String) -> Void)?

    private let appStore: AppStore
    private let locationProvider: any LocationProviding
    private var currentLat: Double?
    private var currentLng: Double?

    init(appStore: AppStore = .shared, locationProvider: any LocationProviding = LocationProvider.shared) {
        self.appStore = appStore
        self.locationProvider = locationProvider
    }

    func loadFromLocal() {
        let scenicList = resolvedScenicList()
        spots = ScenicSpotDisplayMapper.buildItems(
            scenicList: scenicList,
            searchQuery: searchQuery,
            currentLat: currentLat,
            currentLng: currentLng,
            selectedScenicId: appStore.session.currentScenicId
        )
        notifyStateChange()
    }

    func onSearchQueryChange(_ query: String) {
        searchQuery = query
        loadFromLocal()
    }

    func startLocation() async {
        isLocating = true
        notifyStateChange()
        do {
            let snapshot = try await locationProvider.requestSnapshot()
            currentLat = snapshot.latitude
            currentLng = snapshot.longitude
            let address = snapshot.address.trimmingCharacters(in: .whitespacesAndNewlines)
            currentLocationText = address.isEmpty ? "最近的景区" : address
            loadFromLocal()
        } catch LocationProviderError.permissionDenied {
            onShowMessage?("未授予定位权限，无法获取附近景区")
        } catch {
            onShowMessage?("定位失败: \(error.localizedDescription)")
        }
        isLocating = false
        notifyStateChange()
    }

    func selectSpot(_ spot: ScenicSpotDisplayItem) {
        appStore.session.currentScenicId = spot.id
        appStore.session.currentScenicName = spot.name
        NotificationCenter.default.post(
            name: NotificationName.scenicDidChange,
            object: nil,
            userInfo: [
                NotificationUserInfoKey.scenicId: spot.id,
                NotificationUserInfoKey.scenicName: spot.name,
            ]
        )
        loadFromLocal()
        onSelectionComplete?()
    }

    func onApplyNow(api: HomeAPI) async {
        isLoading = true
        notifyStateChange()
        defer {
            isLoading = false
            notifyStateChange()
        }
        do {
            let pendingList = try await api.roleApplyPending()
            if let first = pendingList.first,
               first.status == PermissionApplyPendingStatus.reviewing
                || first.status == PermissionApplyPendingStatus.rejected {
                onNavigateApplyStatus?(first.code)
            } else {
                onNavigateApply?()
            }
        } catch {
            onNavigateApply?()
        }
    }

    private func resolvedScenicList() -> [ScenicInfo] {
        let cached = appStore.permissions.roleScenicList()
        if !cached.isEmpty { return cached }
        let rolePermissionList = appStore.permissions.rolePermissionList()
        guard !rolePermissionList.isEmpty else { return [] }
        return appStore.permissions.matchRolePermissionItem(in: rolePermissionList)?.scenic ?? []
    }

    private func notifyStateChange() {
        onStateChange?()
    }
}
