import CoreLocation
import Foundation

@MainActor
final class LocationTracker: NSObject, ObservableObject, CLLocationManagerDelegate {
    @Published private(set) var running = false
    @Published private(set) var authorization = CLLocationManager.authorizationStatus
    @Published private(set) var lastSync: Date?
    @Published private(set) var error = ""
    private let manager = CLLocationManager()
    private var lastSentAt = Date.distantPast

    override init() {
        super.init(); manager.delegate = self; manager.desiredAccuracy = kCLLocationAccuracyBest; manager.distanceFilter = 3
        manager.activityType = .fitness; manager.pausesLocationUpdatesAutomatically = false; manager.showsBackgroundLocationIndicator = true
    }

    func requestPermission() {
        if authorization == .notDetermined { manager.requestWhenInUseAuthorization() }
        else if authorization == .authorizedWhenInUse { manager.requestAlwaysAuthorization() }
    }

    func start() {
        guard !KeychainStore.read().isEmpty else { error = "Associe d’abord cet iPhone à FilyX."; return }
        requestPermission(); manager.allowsBackgroundLocationUpdates = true; manager.startUpdatingLocation(); manager.startMonitoringSignificantLocationChanges(); running = true
        UserDefaults.standard.set(true, forKey: "filyxTrackingEnabled")
    }

    func stop() { manager.stopUpdatingLocation(); manager.stopMonitoringSignificantLocationChanges(); manager.allowsBackgroundLocationUpdates = false; running = false; UserDefaults.standard.set(false, forKey: "filyxTrackingEnabled") }

    func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) {
        authorization = manager.authorizationStatus
        if authorization == .authorizedWhenInUse { manager.requestAlwaysAuthorization() }
        if authorization == .denied || authorization == .restricted { stop(); error = "Autorise la localisation dans Réglages → FilyX IRL." }
    }

    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        guard running, let location = locations.last, location.horizontalAccuracy >= 0, location.horizontalAccuracy <= 250, Date().timeIntervalSince(lastSentAt) >= 4 else { return }
        lastSentAt = Date()
        Task {
            do { try await APIClient.shared.send(location); lastSync = Date(); error = "" }
            catch { self.error = error.localizedDescription }
        }
    }

    func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) { self.error = error.localizedDescription }
}
