import Combine
import Foundation
import UIKit

@MainActor
final class AppModel: ObservableObject {
    @Published var code = ""
    @Published var deviceName = UIDevice.current.name
    @Published var paired = !KeychainStore.read().isEmpty
    @Published var channelName = UserDefaults.standard.string(forKey: "filyxChannelName") ?? ""
    @Published var tripLabel = "Vérification…"
    @Published var busy = false
    @Published var message = ""
    let tracker = LocationTracker()
    private var trackerChanges: AnyCancellable?

    init() {
        trackerChanges = tracker.objectWillChange.sink { [weak self] _ in self?.objectWillChange.send() }
        if paired && UserDefaults.standard.bool(forKey: "filyxTrackingEnabled") { tracker.start() }
        Task { await refresh() }
    }

    func pair() async {
        let normalized = code.uppercased().filter { $0.isLetter || $0.isNumber }
        guard normalized.count == 8 else { message = "Saisis le code de 8 caractères affiché dans le panel."; return }
        busy = true; defer { busy = false }
        do {
            let response = try await APIClient.shared.pair(code: normalized, deviceName: deviceName)
            try KeychainStore.save(response.device_token); channelName = response.channel.name; UserDefaults.standard.set(channelName, forKey: "filyxChannelName")
            paired = true; message = "iPhone associé à FilyX."; await refresh()
        } catch { message = error.localizedDescription }
    }

    func unpair() { tracker.stop(); KeychainStore.delete(); UserDefaults.standard.removeObject(forKey: "filyxChannelName"); paired = false; channelName = ""; message = "iPhone dissocié." }
    func refresh() async {
        guard paired else { tripLabel = "Téléphone non associé"; return }
        do { let state = try await APIClient.shared.state(); tripLabel = state.tracking_active ? "Trajet en direct · \(state.trip?.name ?? channelName)" : "En attente d’un trajet GPS" }
        catch { tripLabel = error.localizedDescription }
    }
}
