import Foundation
import HealthKit
import CoreLocation

/// Saves a completed walk as an HKWorkout(.walking) with HKWorkoutRoute so it
/// shows up in Apple Health and counts toward the user's Activity rings.
@MainActor
final class WalkHealthSync {
    static let shared = WalkHealthSync()
    private let store = HKHealthStore()

    var isAvailable: Bool { HKHealthStore.isHealthDataAvailable() }

    /// Requests share authorization for workouts + workout routes.
    @discardableResult
    func requestAuthorization() async -> Bool {
        guard isAvailable else { return false }
        let types: Set<HKSampleType> = [
            HKObjectType.workoutType(),
            HKSeriesType.workoutRoute()
        ]
        do {
            try await store.requestAuthorization(toShare: types, read: [])
            return true
        } catch {
            print("WalkHealthSync auth failed: \(error)")
            return false
        }
    }

    func saveWalk(
        points: [GPSPoint],
        startedAt: Date,
        endedAt: Date,
        distanceMeters: Double
    ) async {
        guard isAvailable, points.count >= 2 else { return }

        let configuration = HKWorkoutConfiguration()
        configuration.activityType = .walking
        configuration.locationType = .outdoor

        let builder = HKWorkoutBuilder(
            healthStore: store,
            configuration: configuration,
            device: .local()
        )

        do {
            try await builder.beginCollection(at: startedAt)

            let distanceQuantity = HKQuantity(unit: .meter(), doubleValue: distanceMeters)
            let distanceSample = HKQuantitySample(
                type: HKQuantityType(.distanceWalkingRunning),
                quantity: distanceQuantity,
                start: startedAt,
                end: endedAt
            )
            try await builder.addSamples([distanceSample])

            try await builder.endCollection(at: endedAt)
            guard let workout = try await builder.finishWorkout() else { return }

            // Distribute timestamps evenly across the recorded period — our
            // GPSPoint doesn't carry per-point timing.
            let totalSeconds = endedAt.timeIntervalSince(startedAt)
            let interval = totalSeconds / Double(max(1, points.count - 1))
            let locations = points.enumerated().map { i, p in
                CLLocation(
                    coordinate: CLLocationCoordinate2D(latitude: p.lat, longitude: p.lon),
                    altitude: p.alt ?? 0,
                    horizontalAccuracy: 5,
                    verticalAccuracy: 5,
                    timestamp: startedAt.addingTimeInterval(Double(i) * interval)
                )
            }

            let routeBuilder = HKWorkoutRouteBuilder(healthStore: store, device: .local())
            try await routeBuilder.insertRouteData(locations)
            _ = try await routeBuilder.finishRoute(with: workout, metadata: nil)
        } catch {
            print("WalkHealthSync save failed: \(error)")
        }
    }
}
