//
//  LNLocationManager.swift
//  Lanu
//
//  Created by OneeChan on 2025/12/25.
//

import Foundation
import CoreLocation
import AutoCodable


@AutoCodable
private class LNUserLocation: Codable {
    var latitude: CLLocationDegrees = 0
    var longitude: CLLocationDegrees = 0
    
    init(latitude: CLLocationDegrees, longitude: CLLocationDegrees) {
        self.latitude = latitude
        self.longitude = longitude
    }
}


class LNLocationManager: NSObject {
    static let shared = LNLocationManager()
    private let locationManager = CLLocationManager()
    
    private var curLocation: LNUserLocation? = LNUserDefaults[.location] {
        didSet {
            LNUserDefaults[.location] = curLocation
        }
    }
    private var lastTime: TimeInterval? = LNUserDefaults[.reportLocationTime] {
        didSet {
            LNUserDefaults[.reportLocationTime] = lastTime
        }
    }
    private var shouldReportLocation: Bool {
        guard curLocation != nil, let lastTime else { return true }
        
        return curTime - lastTime > 3 * 60 * 60  // 3 小时内不拉取
    }
    
    private override init() {
        super.init()
        
        locationManager.delegate = self
        locationManager.desiredAccuracy = kCLLocationAccuracyBest  // 最高精度
        
        LNEventDeliver.addObserver(self)
    }
}

extension LNLocationManager: CLLocationManagerDelegate {
    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        guard let userLocation = locations.last else { return }
        
        guard -userLocation.timestamp.timeIntervalSinceNow < 5 else {
            // 只使用5秒内的位置
            Log.d("位置过期，忽略")
            return
        }
        
        guard userLocation.horizontalAccuracy >= 0, userLocation.horizontalAccuracy <= 100 else {
            Log.d("位置精度不足（\(userLocation.horizontalAccuracy)米），继续等待")
            return
        }
        
        manager.stopUpdatingLocation()
        
        curLocation = .init(latitude: userLocation.coordinate.latitude, longitude: userLocation.coordinate.longitude)
        lastTime = curTime
        uploadLocation(coordinate: userLocation.coordinate)
    }
    
    func locationManager(_ manager: CLLocationManager, didFailWithError error: any Error) { }
}

extension LNLocationManager: LNAccountManagerNotify {
    func onUserLogin() {
        getLocationIfNeed()
    }
}

extension LNLocationManager {
    private func getLocationIfNeed() {
        if shouldReportLocation {
            locationManager.requestWhenInUseAuthorization()  // 请求使用时的定位权限
            locationManager.startUpdatingLocation()  // 开始更新位置
        }
    }
    
    private func uploadLocation(coordinate: CLLocationCoordinate2D) {
        LNHttpManager.shared.uploadLocation(
            longitude: coordinate.longitude,
            latitude: coordinate.latitude
        ) { _ in }
    }
}
