//! User-configurable settings for the record daemon.

use serde::{Deserialize, Serialize};
use std::path::PathBuf;

use super::presets::{AudioSettings, EncoderPreset, QualityLevel};
use crate::config::get_default_output_dir;

/// Main settings structure.
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct Settings {
    /// Video recording settings.
    #[serde(default)]
    pub video: VideoSettings,

    /// Output settings.
    #[serde(default)]
    pub output: OutputSettings,

    /// Audio capture settings.
    #[serde(default)]
    pub audio: AudioSettings,

    /// Daemon behavior settings.
    #[serde(default)]
    pub daemon: DaemonSettings,
}

/// Video recording settings.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct VideoSettings {
    /// Encoder preset (codec and quality settings).
    #[serde(default)]
    pub encoder_preset: EncoderPreset,

    /// Quality level preset.
    #[serde(default)]
    pub quality: QualityLevel,

    /// Target frame rate.
    #[serde(default = "default_frame_rate")]
    pub frame_rate: u32,

    /// Enable hardware acceleration.
    #[serde(default = "default_true")]
    pub hardware_acceleration: bool,
}

impl Default for VideoSettings {
    fn default() -> Self {
        Self {
            encoder_preset: EncoderPreset::default(),
            quality: QualityLevel::default(),
            frame_rate: default_frame_rate(),
            hardware_acceleration: true,
        }
    }
}

fn default_frame_rate() -> u32 {
    60
}

fn default_true() -> bool {
    true
}

/// Output settings for recordings.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct OutputSettings {
    /// Directory where recordings will be saved.
    #[serde(default = "default_output_path")]
    pub path: PathBuf,

    /// File naming pattern.
    /// Supports: {date}, {time}, {game_id}, {champion}, {queue_type}
    #[serde(default = "default_naming_pattern")]
    pub naming_pattern: String,

    /// Container format (mp4, mkv, etc.).
    #[serde(default = "default_container")]
    pub container: String,

    /// Split recordings by size (MB). 0 = no splitting.
    #[serde(default)]
    pub split_size_mb: u32,

    /// Split recordings by time (minutes). 0 = no splitting.
    #[serde(default)]
    pub split_time_minutes: u32,
}

impl OutputSettings {
    /// Get the output format enum for this container.
    pub fn output_format(&self) -> crate::recording::OutputFormat {
        crate::recording::OutputFormat::from(self.container.as_str())
    }
}

impl Default for OutputSettings {
    fn default() -> Self {
        Self {
            path: default_output_path(),
            naming_pattern: default_naming_pattern(),
            container: default_container(),
            split_size_mb: 0,
            split_time_minutes: 0,
        }
    }
}

fn default_output_path() -> PathBuf {
    get_default_output_dir().unwrap_or_else(|| PathBuf::from("./recordings"))
}

fn default_naming_pattern() -> String {
    "{date}_{time}_{champion}".to_string()
}

fn default_container() -> String {
    "mp4".to_string()
}

/// Daemon behavior settings.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DaemonSettings {
    /// Automatically start recording when a match begins.
    #[serde(default = "default_true")]
    pub auto_record: bool,

    /// Monitor for League Client startup.
    #[serde(default = "default_true")]
    pub monitor_client: bool,

    /// Polling interval for client detection (milliseconds).
    #[serde(default = "default_poll_interval")]
    pub poll_interval_ms: u64,

    /// IPC socket path. If None, uses default path.
    #[serde(default)]
    pub socket_path: Option<PathBuf>,

    /// Log level (trace, debug, info, warn, error).
    #[serde(default = "default_log_level")]
    pub log_level: String,

    /// Keep event timeline after recording ends.
    #[serde(default = "default_true")]
    pub save_timeline: bool,
}

impl Default for DaemonSettings {
    fn default() -> Self {
        Self {
            auto_record: true,
            monitor_client: true,
            poll_interval_ms: default_poll_interval(),
            socket_path: None,
            log_level: default_log_level(),
            save_timeline: true,
        }
    }
}

fn default_poll_interval() -> u64 {
    1000
}

fn default_log_level() -> String {
    "info".to_string()
}

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

    #[test]
    fn test_default_settings_serialization() {
        let settings = Settings::default();
        let toml_str = toml::to_string_pretty(&settings).unwrap();
        let parsed: Settings = toml::from_str(&toml_str).unwrap();

        assert_eq!(settings.video.frame_rate, parsed.video.frame_rate);
        assert_eq!(settings.daemon.auto_record, parsed.daemon.auto_record);
    }
}
