//
//  NotificationDelegate.swift
//  TheNoiseClock
//
//  Created by Matt Bruce on 9/8/25.
//

import UserNotifications
import Foundation
import Bedrock

/// Delegate to handle notification actions (snooze, stop, etc.)
class NotificationDelegate: NSObject, UNUserNotificationCenterDelegate {
    
    // MARK: - Singleton
    static let shared = NotificationDelegate()
    
    // MARK: - Properties
    private var alarmService: AlarmService?
    
    // MARK: - Initialization
    private override init() {
        super.init()
        setupNotificationCenter()
    }
    
    // MARK: - Setup
    private func setupNotificationCenter() {
        UNUserNotificationCenter.current().delegate = self
        Design.debugLog("[settings] Notification delegate configured")
    }
    
    /// Set the alarm service instance (called from AlarmViewModel)
    func setAlarmService(_ service: AlarmService) {
        self.alarmService = service
    }
    
    // MARK: - UNUserNotificationCenterDelegate
    
    /// Handle notification actions when app is in foreground
    func userNotificationCenter(
        _ center: UNUserNotificationCenter,
        didReceive response: UNNotificationResponse,
        withCompletionHandler completionHandler: @escaping () -> Void
    ) {
        let actionIdentifier = response.actionIdentifier
        let notification = response.notification
        let userInfo = notification.request.content.userInfo
        
        Design.debugLog("[settings] Notification action received: \(actionIdentifier)")
        
        switch actionIdentifier {
        case "SNOOZE_ACTION":
            handleSnoozeAction(userInfo: userInfo)
        case "STOP_ACTION":
            handleStopAction(userInfo: userInfo)
        case UNNotificationDefaultActionIdentifier:
            // User tapped the notification itself
            handleNotificationTap(userInfo: userInfo)
        default:
            Design.debugLog("[settings] Unknown action: \(actionIdentifier)")
        }
        
        completionHandler()
    }
    
    /// Handle notifications when app is in foreground
    func userNotificationCenter(
        _ center: UNUserNotificationCenter,
        willPresent notification: UNNotification,
        withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void
    ) {
        // Show notification even when app is in foreground
        completionHandler([.banner, .sound, .badge])
    }
    
    // MARK: - Action Handlers
    
    private func handleSnoozeAction(userInfo: [AnyHashable: Any]) {
        guard let alarmIdString = userInfo["alarmId"] as? String,
              let alarmId = UUID(uuidString: alarmIdString),
              let alarmService = self.alarmService,
              let alarm = alarmService.getAlarm(id: alarmId) else {
            Design.debugLog("[general] Could not find alarm for snooze action")
            return
        }
        
        Design.debugLog("[settings] Snoozing alarm: \(alarm.label) for \(alarm.snoozeDuration) minutes")
        
        // Calculate snooze time (current time + snooze duration)
        let snoozeTime = Date().addingTimeInterval(TimeInterval(alarm.snoozeDuration * 60))
        Design.debugLog("[settings] Snooze time: \(snoozeTime)")
        Design.debugLog("[settings] Current time: \(Date())")
        
        // Create a temporary alarm for the snooze
        let snoozeAlarm = Alarm(
            id: UUID(), // New ID for snooze alarm
            time: snoozeTime,
            isEnabled: true,
            soundName: alarm.soundName,
            label: "\(alarm.label) (Snoozed)",
            notificationMessage: "Snoozed: \(alarm.notificationMessage)",
            snoozeDuration: alarm.snoozeDuration,
            isVibrationEnabled: alarm.isVibrationEnabled,
            isLightFlashEnabled: alarm.isLightFlashEnabled,
            volume: alarm.volume
        )
        
        // Schedule the snooze notification
        Task {
            await scheduleSnoozeNotification(snoozeAlarm, userInfo: userInfo)
        }
    }
    
    private func handleStopAction(userInfo: [AnyHashable: Any]) {
        guard let alarmIdString = userInfo["alarmId"] as? String,
              let alarmId = UUID(uuidString: alarmIdString) else {
            Design.debugLog("[general] Could not find alarm ID for stop action")
            return
        }
        
        Design.debugLog("[settings] Stopping alarm: \(alarmId)")
        
        // Cancel any pending notifications for this alarm
        UNUserNotificationCenter.current().removePendingNotificationRequests(withIdentifiers: [alarmIdString])
        
        // If this was a snooze alarm, we don't want to disable the original alarm
        // Just cancel the current notification
    }
    
    private func handleNotificationTap(userInfo: [AnyHashable: Any]) {
        guard let alarmIdString = userInfo["alarmId"] as? String,
              let alarmId = UUID(uuidString: alarmIdString) else {
            Design.debugLog("[general] Could not find alarm ID for notification tap")
            return
        }
        
        Design.debugLog("[settings] Notification tapped for alarm: \(alarmId)")
        
        // For now, just log the tap. In the future, this could open the alarm details
        // or perform some other action when the user taps the notification
    }
    
    // MARK: - Private Methods
    
    private func scheduleSnoozeNotification(_ snoozeAlarm: Alarm, userInfo: [AnyHashable: Any]) async {
        let content = UNMutableNotificationContent()
        content.title = snoozeAlarm.label
        content.body = snoozeAlarm.notificationMessage
        content.sound = UNNotificationSound(named: UNNotificationSoundName(rawValue: snoozeAlarm.soundName))
        content.categoryIdentifier = "ALARM_CATEGORY"
        content.userInfo = [
            "alarmId": snoozeAlarm.id.uuidString,
            "soundName": snoozeAlarm.soundName,
            "isSnooze": true,
            "originalAlarmId": userInfo["alarmId"] as? String ?? ""
        ]
        
        // Create trigger for snooze time
        let trigger = UNTimeIntervalNotificationTrigger(
            timeInterval: snoozeAlarm.time.timeIntervalSinceNow,
            repeats: false
        )
        
        // Create request
        let request = UNNotificationRequest(
            identifier: snoozeAlarm.id.uuidString,
            content: content,
            trigger: trigger
        )
        
        // Schedule notification
        do {
            try await UNUserNotificationCenter.current().add(request)
            Design.debugLog("[settings] Snooze notification scheduled for \(snoozeAlarm.time)")
        } catch {
            Design.debugLog("[general] Error scheduling snooze notification: \(error)")
        }
    }
}
