//
// WorkoutSessionManager.swift
// Workouts Watch App
//
// Copyright 2025 Rouslan Zenetl. All Rights Reserved.
//

import Foundation
import HealthKit
import Observation

/// Runs an `HKWorkoutSession` for the duration of a watch workout.
///
/// When the phone launches us via `startWatchApp(toHandle:)`, watchOS hands the app
/// delegate a workout configuration; starting a session with it is what grants the
/// freshly-launched app foreground runtime (and keeps it alive while the wrist is
/// down). We don't record samples — the session exists purely to host the UI.
@Observable
@MainActor
final class WorkoutSessionManager: NSObject {
    private let healthStore = HKHealthStore()
    private var session: HKWorkoutSession?

    private(set) var isRunning = false

    /// Prompt for workout-sharing authorization. Called once at launch so a later
    /// phone-initiated launch can start a session without first hitting a permission
    /// wall.
    func requestAuthorization() {
        guard HKHealthStore.isHealthDataAvailable() else { return }
        healthStore.requestAuthorization(toShare: [.workoutType()], read: []) { _, _ in }
    }

    /// Start the session for a phone-launched workout. Idempotent — a second launch
    /// while one is already running is ignored.
    func start(with configuration: HKWorkoutConfiguration) {
        guard HKHealthStore.isHealthDataAvailable(), session == nil else { return }
        do {
            let session = try HKWorkoutSession(healthStore: healthStore, configuration: configuration)
            session.delegate = self
            self.session = session
            session.startActivity(with: Date())
            isRunning = true
        } catch {
            session = nil
            isRunning = false
        }
    }

    /// End the session — called when the workout finishes (no active workout remains).
    func end() {
        session?.end()
        clear()
    }

    private func clear() {
        session = nil
        isRunning = false
    }
}

// MARK: - HKWorkoutSessionDelegate

extension WorkoutSessionManager: HKWorkoutSessionDelegate {
    nonisolated func workoutSession(
        _ workoutSession: HKWorkoutSession,
        didChangeTo toState: HKWorkoutSessionState,
        from fromState: HKWorkoutSessionState,
        date: Date
    ) {
        guard toState == .ended || toState == .stopped else { return }
        Task { @MainActor in self.clear() }
    }

    nonisolated func workoutSession(_ workoutSession: HKWorkoutSession, didFailWithError error: Error) {
        Task { @MainActor in self.clear() }
    }
}
