use std::path::PathBuf;

use serde::{
    Deserialize,
    Serialize,
};

/// Application configuration loaded from TOML file.
///
/// Configuration is loaded from `~/.config/nimue/config.toml`.
/// If the file does not exist, default values are used.
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(default)]
pub struct Config {
    /// Initial font size for terminals (default: 13.0)
    pub font_size: f32,
    /// Shell command to use for terminals (default: "nu")
    pub shell: String,
    /// Command for the top-left terminal (default: "opencode")
    pub corner_command: String,
}

impl Default for Config {
    fn default() -> Self {
        Self {
            font_size: 13.0,
            shell: "nu".to_string(),
            corner_command: "opencode".to_string(),
        }
    }
}

impl Config {
    /// Load configuration from the default config path.
    ///
    /// Returns default config if the file doesn't exist or can't be parsed.
    pub fn load() -> Self {
        let config_path = Self::config_path();

        if !config_path.exists() {
            return Self::default();
        }

        let contents = std::fs::read_to_string(&config_path);
        match contents {
            Ok(contents) => match toml::from_str(&contents) {
                Ok(config) => config,
                Err(e) => {
                    eprintln!(
                        "Warning: Failed to parse config file at {:?}: {}. Using defaults.",
                        config_path, e
                    );
                    Self::default()
                }
            },
            Err(e) => {
                eprintln!(
                    "Warning: Failed to read config file at {:?}: {}. Using defaults.",
                    config_path, e
                );
                Self::default()
            }
        }
    }

    /// Returns the path to the configuration file (~/.config/nimue/config.toml).
    fn config_path() -> PathBuf {
        let config_dir = dirs::config_dir().unwrap_or_else(|| PathBuf::from("."));
        config_dir.join("nimue").join("config.toml")
    }
}

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

    #[test]
    fn test_config_defaults() {
        let config = Config::default();
        assert_eq!(config.font_size, 13.0);
        assert_eq!(config.shell, "nu");
        assert_eq!(config.corner_command, "opencode");
    }

    #[test]
    fn test_config_toml_parsing() {
        let toml_str = r#"
font_size = 16.0
shell = "bash"
corner_command = "vim"
"#;
        let config: Config = toml::from_str(toml_str).unwrap();
        assert_eq!(config.font_size, 16.0);
        assert_eq!(config.shell, "bash");
        assert_eq!(config.corner_command, "vim");
    }
}
