//
//  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: [Sound]
    public let settings: AudioSettings
    
    public init(sounds: [Sound], settings: AudioSettings) {
        self.sounds = sounds
        self.settings = settings
    }
}

/// Simple struct for loading just the sounds array from category JSON files
public struct SoundsOnly: Codable {
    public let sounds: [Sound]
    
    public init(sounds: [Sound]) {
        self.sounds = sounds
    }
}



/// 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 audio settings from SoundsSettings.json
    private func loadAudioSettings(from bundle: Bundle = .main) -> AudioSettings {
        guard let url = bundle.url(forResource: "SoundsSettings", withExtension: "json") else {
            print("⚠️ Warning: SoundsSettings.json not found, using default settings")
            return AudioSettings(
                defaultVolume: 0.8,
                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)
            print("✅ Loaded audio settings from SoundsSettings.json")
            return settings
        } catch {
            print("⚠️ Warning: Error loading audio settings, using defaults: \(error)")
            return AudioSettings(
                defaultVolume: 0.8,
                defaultLoopCount: -1,
                preloadSounds: true,
                preloadStrategy: "category",
                audioSessionCategory: "playback",
                audioSessionMode: "default",
                audioSessionOptions: ["mixWithOthers"]
            )
        }
    }
    
    /// Load sound configuration from multiple category-specific JSON files
    public func loadConfigurationFromBundles(from bundle: Bundle = .main) -> SoundConfiguration {
        let bundleNames = ["Colored", "Nature", "Mechanical", "Ambient"]
        var allSounds: [Sound] = []
        
        for bundleName in bundleNames {
            guard let bundleURL = bundle.url(forResource: bundleName, withExtension: "bundle"),
                  let categoryBundle = Bundle(url: bundleURL),
                  let url = categoryBundle.url(forResource: "sounds", withExtension: "json") else {
                print("⚠️ Warning: Could not find sounds.json in \(bundleName).bundle")
                continue
            }
            
            do {
                let data = try Data(contentsOf: url)
                let soundsOnly = try JSONDecoder().decode(SoundsOnly.self, from: data)
                allSounds.append(contentsOf: soundsOnly.sounds)
                
                print("✅ Loaded \(soundsOnly.sounds.count) sounds from \(bundleName).bundle")
            } catch {
                print("⚠️ Warning: Error loading sounds from \(bundleName).bundle: \(error)")
            }
        }
        
        // Load settings from separate file
        let settings = loadAudioSettings(from: bundle)
        
        let config = SoundConfiguration(sounds: allSounds, settings: settings)
        self.configuration = config
        print("✅ Loaded combined sound configuration with \(allSounds.count) sounds from \(bundleNames.count) bundles")
        return config
    }
    
    /// Get current configuration
    public func getConfiguration() -> SoundConfiguration {
        if configuration == nil {
            return loadConfigurationFromBundles()
        }
        return configuration!
    }
    
    /// Get all available sounds
    public func getAvailableSounds() -> [Sound] {
        return getConfiguration().sounds
    }
    
    /// Get sounds by category
    public func getSoundsByCategory(_ categoryId: String) -> [Sound] {
        return getConfiguration().sounds
            .filter { $0.category == categoryId }
    }
    
    
    /// Get audio settings
    public func getAudioSettings() -> AudioSettings {
        return getConfiguration().settings
    }
    
}
