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

import Foundation
import AudioPlaybackKit
import Bedrock

/// Extension service for alarm-specific sound functionality
class AlarmSoundService {
    static let shared = AlarmSoundService()
    
    // MARK: - Constants
    /// The category ID for alarm sounds as defined in alarm-sounds.json
    static let alarmCategoryId = "alarm"
    
    private init() {}
    
    /// Load alarm sound configuration from AlarmSounds.bundle
    private func loadAlarmConfiguration() -> SoundConfiguration {
        guard let bundleURL = Bundle.main.url(forResource: "AlarmSounds", withExtension: "bundle"),
              let alarmBundle = Bundle(url: bundleURL),
              let url = alarmBundle.url(forResource: "sounds", withExtension: "json") else {
            fatalError("❌ sounds.json not found in AlarmSounds.bundle. Ensure the bundle and file exist.")
        }
        
        do {
            let data = try Data(contentsOf: url)
            let soundsOnly = try JSONDecoder().decode(SoundsOnly.self, from: data)
            
            // Load settings from separate SoundsSettings.json file
            let settings = loadAudioSettings()
            
            return SoundConfiguration(sounds: soundsOnly.sounds, settings: settings)
        } catch {
            fatalError("❌ Error loading alarm sound configuration: \(error)")
        }
    }
    
    /// Load audio settings from SoundsSettings.json
    private func loadAudioSettings() -> AudioSettings {
        guard let url = Bundle.main.url(forResource: "SoundsSettings", withExtension: "json") else {
            Design.debugLog("[general] Warning: SoundsSettings.json not found, using default alarm settings")
            return AudioSettings(
                defaultVolume: 1.0,
                defaultLoopCount: -1,
                preloadSounds: true,
                preloadStrategy: "category",
                audioSessionCategory: "playback",
                audioSessionMode: "default",
                audioSessionOptions: ["mixWithOthers"]
            )
        }
        
        do {
            let data = try Data(contentsOf: url)
            let settings = try JSONDecoder().decode(AudioSettings.self, from: data)
            Design.debugLog("[settings] Loaded audio settings for alarms from SoundsSettings.json")
            return settings
        } catch {
            Design.debugLog("[general] Warning: Error loading audio settings for alarms, using defaults: \(error)")
            return AudioSettings(
                defaultVolume: 1.0,
                defaultLoopCount: -1,
                preloadSounds: true,
                preloadStrategy: "category",
                audioSessionCategory: "playback",
                audioSessionMode: "default",
                audioSessionOptions: ["mixWithOthers"]
            )
        }
    }
    
    /// Get all available alarm sounds
    func getAlarmSounds() -> [Sound] {
        return loadAlarmConfiguration().sounds
    }
    
    /// Get alarm sounds by category
    func getAlarmSoundsByCategory(_ categoryId: String) -> [Sound] {
        return loadAlarmConfiguration().sounds
            .filter { $0.category == categoryId }
    }
    
    /// Get alarm sounds for the default alarm category
    func getAlarmSoundsForDefaultCategory() -> [Sound] {
        return getAlarmSoundsByCategory(Self.alarmCategoryId)
    }
    
    /// Get default alarm sound
    func getDefaultAlarmSound() -> Sound? {
        let sounds = loadAlarmConfiguration().sounds
        return sounds.first { $0.isDefault == true } ?? sounds.first
    }
    
    /// Get alarm sound categories
    func getAlarmSoundCategories() -> [TheNoiseClock.SoundCategory] {
        return [.alarm]
    }
    
    /// Get alarm sound settings
    func getAlarmSoundSettings() -> AudioSettings {
        return loadAlarmConfiguration().settings
    }
    
    /// Get sound display name by filename
    func getSoundDisplayName(_ fileName: String) -> String {
        let alarmSounds = getAlarmSounds()
        if let sound = alarmSounds.first(where: { $0.fileName == fileName }) {
            return sound.name
        }
        return fileName.replacingOccurrences(of: ".caf", with: "").capitalized
    }
}
