//
//  SoundConfiguration.swift
//  AudioPlaybackKit
//
//  Created by Matt Bruce on 9/8/25.
//

import Foundation

/// Configuration model for sound system loaded from JSON
public struct SoundConfiguration: Codable {
    public let sounds: [SoundConfig]
    public let categories: [SoundCategory]
    public let settings: AudioSettings
    
    public init(sounds: [SoundConfig], categories: [SoundCategory], settings: AudioSettings) {
        self.sounds = sounds
        self.categories = categories
        self.settings = settings
    }
}

/// Individual sound configuration
public struct SoundConfig: Codable, Identifiable {
    public let id: String
    public let name: String
    public let fileName: String
    public let category: String
    public let description: String
    public let bundleName: String? // Optional bundle name for organization
    
    public init(id: String, name: String, fileName: String, category: String, description: String, bundleName: String? = nil) {
        self.id = id
        self.name = name
        self.fileName = fileName
        self.category = category
        self.description = description
        self.bundleName = bundleName
    }
    
    /// Convert to Sound model for compatibility
    public func toSound() -> Sound {
        return Sound(name: name, fileName: fileName, category: category, description: description, bundleName: bundleName)
    }
}

/// Sound category configuration
public struct SoundCategory: Codable, Identifiable {
    public let id: String
    public let name: String
    public let description: String
    public let bundleName: String? // Optional bundle name for this category
    
    public init(id: String, name: String, description: String, bundleName: String? = nil) {
        self.id = id
        self.name = name
        self.description = description
        self.bundleName = bundleName
    }
}

/// Audio settings configuration
public struct AudioSettings: Codable {
    public let defaultVolume: Float
    public let defaultLoopCount: Int
    public let preloadSounds: Bool
    public let preloadStrategy: String // "all", "category", "none"
    public let audioSessionCategory: String
    public let audioSessionMode: String
    public let audioSessionOptions: [String]
    
    public init(defaultVolume: Float, defaultLoopCount: Int, preloadSounds: Bool, preloadStrategy: String, audioSessionCategory: String, audioSessionMode: String, audioSessionOptions: [String]) {
        self.defaultVolume = defaultVolume
        self.defaultLoopCount = defaultLoopCount
        self.preloadSounds = preloadSounds
        self.preloadStrategy = preloadStrategy
        self.audioSessionCategory = audioSessionCategory
        self.audioSessionMode = audioSessionMode
        self.audioSessionOptions = audioSessionOptions
    }
}

/// Service for loading and managing sound configuration
public class SoundConfigurationService {
    public static let shared = SoundConfigurationService()
    
    private var configuration: SoundConfiguration?
    
    private init() {}
    
    /// Load sound configuration from JSON file
    public func loadConfiguration(from bundle: Bundle = .main, fileName: String = "sounds") -> SoundConfiguration? {
        guard let url = bundle.url(forResource: fileName, withExtension: "json") else {
            print("❌ \(fileName).json not found in bundle")
            return nil
        }
        
        do {
            let data = try Data(contentsOf: url)
            let config = try JSONDecoder().decode(SoundConfiguration.self, from: data)
            self.configuration = config
            print("✅ Loaded sound configuration with \(config.sounds.count) sounds")
            return config
        } catch {
            print("❌ Error loading sound configuration: \(error)")
            return nil
        }
    }
    
    /// Get current configuration
    public func getConfiguration() -> SoundConfiguration? {
        if configuration == nil {
            return loadConfiguration()
        }
        return configuration
    }
    
    /// Get all available sounds
    public func getAvailableSounds() -> [Sound] {
        guard let config = getConfiguration() else {
            print("⚠️ No configuration available, falling back to constants")
            return getFallbackSounds()
        }
        
        return config.sounds.map { $0.toSound() }
    }
    
    /// Get sounds by category
    public func getSoundsByCategory(_ categoryId: String) -> [Sound] {
        guard let config = getConfiguration() else {
            return []
        }
        
        return config.sounds
            .filter { $0.category == categoryId }
            .map { $0.toSound() }
    }
    
    /// Get sounds by bundle name
    public func getSoundsByBundle(_ bundleName: String) -> [Sound] {
        guard let config = getConfiguration() else {
            return []
        }
        
        return config.sounds
            .filter { $0.bundleName == bundleName }
            .map { $0.toSound() }
    }
    
    /// Get alarm sounds specifically
    public func getAlarmSounds() -> [Sound] {
        return getSoundsByCategory("alarm")
    }
    
    /// Get available categories
    public func getAvailableCategories() -> [SoundCategory] {
        return getConfiguration()?.categories ?? []
    }
    
    /// Get audio settings
    public func getAudioSettings() -> AudioSettings? {
        return getConfiguration()?.settings
    }
    
    /// Fallback sounds if JSON loading fails
    private func getFallbackSounds() -> [Sound] {
        return [
            // White noise sounds
            Sound(name: "White Noise", fileName: "white-noise.mp3", category: "ambient", description: "Classic white noise for focus and relaxation", bundleName: "Ambient"),
            Sound(name: "Heavy Rain White Noise", fileName: "heavy-rain-white-noise.mp3", category: "nature", description: "Heavy rainfall sounds for peaceful sleep", bundleName: "Nature"),
            Sound(name: "Fan White Noise", fileName: "fan-white-noise-heater.mp3", category: "mechanical", description: "Fan and heater sounds for consistent background noise", bundleName: "Mechanical"),
            
            // Alarm sounds
            Sound(name: "Digital Alarm", fileName: "digital-alarm.mp3", category: "alarm", description: "Classic digital alarm sound", bundleName: "AlarmSounds"),
            Sound(name: "iPhone Alarm", fileName: "iphone-alarm.mp3", category: "alarm", description: "iPhone-style alarm sound", bundleName: "AlarmSounds"),
            Sound(name: "Classic Alarm", fileName: "classic-alarm.mp3", category: "alarm", description: "Traditional alarm sound", bundleName: "AlarmSounds"),
            Sound(name: "Beep Alarm", fileName: "beep-alarm.mp3", category: "alarm", description: "Short beep alarm sound", bundleName: "AlarmSounds"),
            Sound(name: "Siren Alarm", fileName: "siren-alarm.mp3", category: "alarm", description: "Emergency siren alarm for heavy sleepers", bundleName: "AlarmSounds"),
            Sound(name: "Voice Wake Up", fileName: "voice-wakeup.mp3", category: "alarm", description: "Voice-based wake up sound", bundleName: "AlarmSounds")
        ]
    }
}
