//
// WorkoutActivityAttributes.swift
// Workouts (shared: iOS app + Workouts Widget)
//
// Copyright 2025 Rouslan Zenetl. All Rights Reserved.
//

import ActivityKit
import Foundation

/// The ActivityKit attributes backing the active-workout Live Activity (lock screen +
/// Dynamic Island). This file is compiled into **both** the iOS app (which starts / updates /
/// ends the activity via `WorkoutLiveActivityController`) and the `Workouts Widget` extension
/// (which renders it). It intentionally depends on nothing but ActivityKit + Foundation, so it
/// can live in the widget target without pulling in the app's model/sync layer.
///
/// The whole design is **push-free**: every content state carries wall-clock anchors
/// (`phaseStart` / `phaseEnd`), so the widget renders live countdowns with
/// `Text(timerInterval:)` / `ProgressView(timerInterval:)` and never needs a server or a
/// background update to keep ticking — the same wall-clock-anchored trick the in-app run flow
/// and the watch mirror already use.
struct WorkoutActivityAttributes: ActivityAttributes {
    /// The dynamic part of the activity — mirrors one page of the Ready → Work → Rest → Finish
    /// run flow. Refreshed by the app on every phase / set transition while it's foregrounded.
    struct ContentState: Codable, Hashable, Sendable {
        /// Which page of the run flow the driving device is on.
        enum Phase: String, Codable, Hashable, Sendable {
            case ready, work, rest, done
        }

        var exerciseName: String
        var phase: Phase

        /// 0-based set this frame pertains to, and the planned total.
        var setIndex: Int
        var setCount: Int

        /// Footer line under the timer, e.g. "8 reps" or "30 sec".
        var detail: String

        /// Wall-clock anchor for the phase's timer. A count-up work set counts up from here; a
        /// count-down phase (rest / timed work / auto-Done) runs from here to `phaseEnd`.
        var phaseStart: Date

        /// End anchor for a count-down phase; `nil` for a rep-based work set (which counts up)
        /// or the Ready lead-in (which shows no timer).
        var phaseEnd: Date?

        // MARK: Derived (shared by every widget presentation)

        /// 1-based set number for display.
        var setNumber: Int { setIndex + 1 }

        /// A running count-down is present (rest, timed work, or the auto-Done deadline).
        var isCountingDown: Bool { phaseEnd != nil }

        /// A rep-based work set that counts up (no end anchor).
        var isCountingUp: Bool { phase == .work && phaseEnd == nil }

        /// Short phase word for the compact/expanded labels.
        var phaseTitle: String {
            switch phase {
            case .ready: return "Ready"
            case .work:  return "Work"
            case .rest:  return "Rest"
            case .done:  return "Done"
            }
        }

        /// One-line status under the exercise name, e.g. "Rest · Set 2 of 4" or
        /// "Set 2 of 4 · 8 reps".
        var statusLine: String {
            let sets = "Set \(setNumber) of \(setCount)"
            switch phase {
            case .ready: return "Ready · \(sets)"
            case .work:  return detail.isEmpty ? sets : "\(sets) · \(detail)"
            case .rest:  return "Rest · \(sets)"
            case .done:  return "Complete"
            }
        }
    }
}
