//
//  AlarmViewModel.swift
//  TheNoiseClock
//
//  Created by Matt Bruce on 9/7/25.
//

import AlarmKit
import Bedrock
import Foundation
import Observation

/// ViewModel for alarm management using AlarmKit (iOS 26+).
/// AlarmKit provides alarms that cut through Focus modes and silent mode,
/// with built-in Live Activity countdown and system alarm UI.
@Observable
class AlarmViewModel {
    
    // MARK: - Properties
    private let alarmService: AlarmService
    private let alarmKitService = AlarmKitService.shared
    
    /// Whether AlarmKit is authorized
    var isAlarmKitAuthorized: Bool {
        alarmKitService.authorizationState == .authorized
    }
    
    var alarms: [Alarm] {
        alarmService.alarms
    }
    
    var systemSounds: [String] {
        AppConstants.SystemSounds.availableSounds
    }

    // MARK: - Initialization
    init(alarmService: AlarmService = AlarmService()) {
        self.alarmService = alarmService
    }
    
    // MARK: - Authorization
    
    /// Request AlarmKit authorization. Should be called during onboarding.
    func requestAlarmKitAuthorization() async -> Bool {
        return await alarmKitService.requestAuthorization()
    }
    
    // MARK: - Alarm CRUD Operations
    
    func addAlarm(_ alarm: Alarm) async {
        alarmService.addAlarm(alarm)
        
        // Schedule with AlarmKit if alarm is enabled
        if alarm.isEnabled {
            Design.debugLog("[alarms] Scheduling AlarmKit alarm for \(alarm.label)")
            do {
                try await alarmKitService.scheduleAlarm(alarm)
            } catch {
                Design.debugLog("[alarms] AlarmKit scheduling failed: \(error)")
            }
        }
    }
    
    func updateAlarm(_ alarm: Alarm) async {
        alarmService.updateAlarm(alarm)
        
        // Cancel existing and reschedule if enabled
        alarmKitService.cancelAlarm(id: alarm.id)
        
        if alarm.isEnabled {
            Design.debugLog("[alarms] Rescheduling AlarmKit alarm for \(alarm.label)")
            do {
                try await alarmKitService.scheduleAlarm(alarm)
            } catch {
                Design.debugLog("[alarms] AlarmKit rescheduling failed: \(error)")
            }
        }
    }
    
    func deleteAlarm(id: UUID) async {
        // Cancel AlarmKit alarm first
        alarmKitService.cancelAlarm(id: id)
        
        // Then delete from storage
        alarmService.deleteAlarm(id: id)
    }
    
    func toggleAlarm(id: UUID) async {
        guard var alarm = alarmService.getAlarm(id: id) else { return }
        
        alarm.isEnabled.toggle()
        alarmService.updateAlarm(alarm)
        
        // Schedule or cancel based on new state
        if alarm.isEnabled {
            Design.debugLog("[alarms] Enabling AlarmKit alarm \(alarm.label)")
            do {
                try await alarmKitService.scheduleAlarm(alarm)
            } catch {
                Design.debugLog("[alarms] AlarmKit scheduling failed: \(error)")
            }
        } else {
            alarmKitService.cancelAlarm(id: id)
        }
    }
    
    func getAlarm(id: UUID) -> Alarm? {
        return alarmService.getAlarm(id: id)
    }
    
    func createNewAlarm(
        time: Date,
        soundName: String = AppConstants.SystemSounds.defaultSound,
        label: String = "Alarm",
        notificationMessage: String = "Your alarm is ringing",
        snoozeDuration: Int = 9,
        isVibrationEnabled: Bool = true,
        isLightFlashEnabled: Bool = false,
        volume: Float = 1.0
    ) -> Alarm {
        return Alarm(
            id: UUID(),
            time: time,
            isEnabled: true,
            soundName: soundName,
            label: label,
            notificationMessage: notificationMessage,
            snoozeDuration: snoozeDuration,
            isVibrationEnabled: isVibrationEnabled,
            isLightFlashEnabled: isLightFlashEnabled,
            volume: volume
        )
    }
    
    // MARK: - App Lifecycle
    
    /// Reschedule all enabled alarms with AlarmKit.
    /// Call this on app launch to ensure alarms are registered.
    func rescheduleAllAlarms() async {
        Design.debugLog("[alarmkit] ========== RESCHEDULING ALL ALARMS ==========")
        
        let enabledAlarms = alarmService.getEnabledAlarms()
        Design.debugLog("[alarmkit] Found \(enabledAlarms.count) enabled alarm(s)")
        
        for alarm in enabledAlarms {
            Design.debugLog("[alarmkit] Scheduling: \(alarm.label) at \(alarm.time)")
            do {
                try await alarmKitService.scheduleAlarm(alarm)
            } catch {
                Design.debugLog("[alarmkit] ❌ Failed to reschedule \(alarm.label): \(error)")
            }
        }
        
        Design.debugLog("[alarmkit] ========== RESCHEDULING COMPLETE ==========")
        alarmKitService.logCurrentAlarms()
    }
}
