//! TRACES: UR-023, UR-031, UR-032, UR-033 | DR-034, DR-035, DR-036, DR-048

use serde::{Deserialize, Serialize};

/// Volume normalization levels matching Spotify's presets
#[derive(specta::Type, Debug, Clone, Copy, PartialEq, Serialize, Deserialize, Default)]
#[serde(rename_all = "lowercase")]
pub enum VolumeLevel {
    /// Louder output (-11 LUFS)
    Loud,
    /// Default level (-14 LUFS)
    #[default]
    Normal,
    /// Quieter output (-23 LUFS)
    Quiet,
}

impl VolumeLevel {
    /// Get the target LUFS value for this volume level
    pub fn target_lufs(&self) -> f32 {
        match self {
            VolumeLevel::Loud => -11.0,
            VolumeLevel::Normal => -14.0,
            VolumeLevel::Quiet => -23.0,
        }
    }
}

/// Audio playback settings
#[derive(specta::Type, Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct AudioSettings {
    /// Crossfade duration in seconds (0 = disabled, max 12)
    pub crossfade_duration: f32,
    /// Enable gapless playback between tracks
    pub gapless_playback: bool,
    /// Enable volume normalization
    pub normalize_volume: bool,
    /// Target volume level for normalization
    pub volume_level: VolumeLevel,
}

impl Default for AudioSettings {
    fn default() -> Self {
        Self {
            crossfade_duration: 0.0,
            gapless_playback: true,
            normalize_volume: false,
            volume_level: VolumeLevel::Normal,
        }
    }
}

impl AudioSettings {
    /// Clamp crossfade duration to valid range (0-12 seconds)
    pub fn with_crossfade_clamped(mut self) -> Self {
        self.crossfade_duration = self.crossfade_duration.clamp(0.0, 12.0);
        self
    }
}

/// Video playback settings
#[derive(specta::Type, Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct VideoSettings {
    /// Enable auto-play of next episode (with countdown)
    pub auto_play_next_episode: bool,
    /// Countdown duration in seconds before auto-play (5-30 seconds)
    pub auto_play_countdown_seconds: u32,
    /// Maximum number of episodes to auto-play consecutively (0 = unlimited)
    #[serde(default)]
    pub auto_play_max_episodes: u32,
}

impl Default for VideoSettings {
    fn default() -> Self {
        Self {
            auto_play_next_episode: true,
            auto_play_countdown_seconds: 10,
            auto_play_max_episodes: 0,
        }
    }
}

impl VideoSettings {
    /// Clamp countdown duration to valid range (5-30 seconds)
    pub fn with_countdown_clamped(mut self) -> Self {
        self.auto_play_countdown_seconds = self.auto_play_countdown_seconds.clamp(5, 30);
        self
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_default_settings() {
        let settings = AudioSettings::default();
        assert_eq!(settings.crossfade_duration, 0.0);
        assert!(settings.gapless_playback);
        assert!(!settings.normalize_volume);
        assert_eq!(settings.volume_level, VolumeLevel::Normal);
    }

    #[test]
    fn test_volume_level_lufs() {
        assert_eq!(VolumeLevel::Loud.target_lufs(), -11.0);
        assert_eq!(VolumeLevel::Normal.target_lufs(), -14.0);
        assert_eq!(VolumeLevel::Quiet.target_lufs(), -23.0);
    }

    #[test]
    fn test_crossfade_clamping() {
        let settings = AudioSettings {
            crossfade_duration: 20.0,
            ..Default::default()
        }
        .with_crossfade_clamped();
        assert_eq!(settings.crossfade_duration, 12.0);

        let settings = AudioSettings {
            crossfade_duration: -5.0,
            ..Default::default()
        }
        .with_crossfade_clamped();
        assert_eq!(settings.crossfade_duration, 0.0);
    }

    #[test]
    fn test_settings_serialization() {
        let settings = AudioSettings {
            crossfade_duration: 5.0,
            gapless_playback: true,
            normalize_volume: true,
            volume_level: VolumeLevel::Loud,
        };

        let json = serde_json::to_string(&settings).unwrap();
        assert!(json.contains("\"crossfadeDuration\":5.0"));
        assert!(json.contains("\"gaplessPlayback\":true"));
        assert!(json.contains("\"normalizeVolume\":true"));
        assert!(json.contains("\"volumeLevel\":\"loud\""));

        let parsed: AudioSettings = serde_json::from_str(&json).unwrap();
        assert_eq!(parsed.crossfade_duration, 5.0);
        assert_eq!(parsed.volume_level, VolumeLevel::Loud);
    }

    #[test]
    fn test_video_default_settings() {
        let settings = VideoSettings::default();
        assert!(settings.auto_play_next_episode);
        assert_eq!(settings.auto_play_countdown_seconds, 10);
        assert_eq!(settings.auto_play_max_episodes, 0);
    }

    #[test]
    fn test_video_countdown_clamping() {
        let settings = VideoSettings {
            auto_play_countdown_seconds: 60,
            ..Default::default()
        }
        .with_countdown_clamped();
        assert_eq!(settings.auto_play_countdown_seconds, 30);

        let settings = VideoSettings {
            auto_play_countdown_seconds: 2,
            ..Default::default()
        }
        .with_countdown_clamped();
        assert_eq!(settings.auto_play_countdown_seconds, 5);
    }

    #[test]
    fn test_video_settings_serialization() {
        let settings = VideoSettings {
            auto_play_next_episode: false,
            auto_play_countdown_seconds: 15,
            auto_play_max_episodes: 5,
        };

        let json = serde_json::to_string(&settings).unwrap();
        assert!(json.contains("\"autoPlayNextEpisode\":false"));
        assert!(json.contains("\"autoPlayCountdownSeconds\":15"));
        assert!(json.contains("\"autoPlayMaxEpisodes\":5"));

        let parsed: VideoSettings = serde_json::from_str(&json).unwrap();
        assert!(!parsed.auto_play_next_episode);
        assert_eq!(parsed.auto_play_countdown_seconds, 15);
        assert_eq!(parsed.auto_play_max_episodes, 5);
    }

    #[test]
    fn test_video_settings_backward_compat() {
        // Old JSON without auto_play_max_episodes field
        let json = r#"{"autoPlayNextEpisode":true,"autoPlayCountdownSeconds":10}"#;
        let parsed: VideoSettings = serde_json::from_str(json).unwrap();
        assert!(parsed.auto_play_next_episode);
        assert_eq!(parsed.auto_play_countdown_seconds, 10);
        assert_eq!(parsed.auto_play_max_episodes, 0);
    }
}
