#if os(iOS)
import ActivityKit
import Foundation
import os.log

private let logger = Logger(subsystem: Bundle.main.bundleIdentifier ?? "ABS", category: "LiveActivity")

/// Manages one `Activity<DownloadActivityAttributes>` per active download key.
/// All methods must be called from the MainActor (same isolation as DownloadManager).
@MainActor
final class DownloadActivityManager {

    // Keyed by downloadKey (matches DownloadManager's key scheme).
    private var activities: [String: Activity<DownloadActivityAttributes>] = [:]

    /// Requests a new Live Activity for a download that is starting.
    /// Logs the reason to the console (visible in Xcode) if the request fails.
    func startActivity(downloadKey: String, itemTitle: String) {
        let authInfo = ActivityAuthorizationInfo()
        guard authInfo.areActivitiesEnabled else {
            logger.warning("Live Activities disabled (areActivitiesEnabled=false) — skipping for '\(itemTitle)'")
            return
        }

        let attributes = DownloadActivityAttributes(itemTitle: itemTitle)
        let initial = DownloadActivityAttributes.ContentState(
            progress: 0,
            bytesDownloaded: 0
        )
        let content = ActivityContent(state: initial, staleDate: nil)

        do {
            let activity = try Activity.request(attributes: attributes, content: content)
            activities[downloadKey] = activity
            logger.info("Live Activity started: id=\(activity.id) title='\(itemTitle)'")
        } catch {
            // Most common reason: no widget extension is installed/embedded that
            // provides an ActivityConfiguration for DownloadActivityAttributes.
            logger.error("Activity.request() failed: \(error.localizedDescription)")
        }
    }

    /// Pushes an incremental progress update to the running Live Activity.
    func updateActivity(downloadKey: String, progress: Double, bytesDownloaded: Int64) {
        guard let activity = activities[downloadKey] else { return }
        let state = DownloadActivityAttributes.ContentState(
            progress: progress,
            bytesDownloaded: bytesDownloaded
        )
        let content = ActivityContent(state: state, staleDate: nil)
        // activity.update() is async; fire-and-forget is intentional — a skipped
        // frame doesn't hurt the download and avoids blocking the download loop.
        Task { await activity.update(content) }
    }

    /// Ends the Live Activity with `.immediate` dismissal so the Lock Screen
    /// badge disappears right away instead of lingering for the default 4 hours.
    func endActivity(downloadKey: String) {
        guard let activity = activities.removeValue(forKey: downloadKey) else { return }
        Task { await activity.end(nil, dismissalPolicy: .immediate) }
    }
}
#endif
