//! Configuration management

use crate::constants::{APP_NAME, CONFIG_FILE_NAME, DEFAULT_CONCURRENT_CHECKS};
use crate::error::{LazyDomainError, Result};
use serde::{Deserialize, Serialize};
use std::path::PathBuf;

/// Application configuration
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Config {
    /// Number of concurrent domain checks
    pub concurrency: usize,
    /// Default TLD preset to use
    pub default_preset: String,
    /// Color theme (dark/light)
    pub theme: String,
}

impl Config {
    /// Creates a new Config with default values
    pub fn new() -> Self {
        Config {
            concurrency: DEFAULT_CONCURRENT_CHECKS,
            default_preset: "Popular".to_string(),
            theme: "dark".to_string(),
        }
    }

    /// Loads config from the default config file
    pub fn load() -> Result<Self> {
        let config_path = Self::config_path()?;
        
        if !config_path.exists() {
            // Create default config
            let config = Config::new();
            config.save()?;
            return Ok(config);
        }

        let content = std::fs::read_to_string(&config_path)?;
        let config: Config = toml::from_str(&content)
            .map_err(|e| LazyDomainError::ConfigError(e.to_string()))?;
        
        Ok(config)
    }

    /// Saves config to the default config file
    pub fn save(&self) -> Result<()> {
        let config_path = Self::config_path()?;
        
        // Create config directory if it doesn't exist
        if let Some(parent) = config_path.parent() {
            std::fs::create_dir_all(parent)?;
        }

        let content = toml::to_string_pretty(self)
            .map_err(|e| LazyDomainError::ConfigError(e.to_string()))?;
        
        std::fs::write(&config_path, content)?;
        
        Ok(())
    }

    /// Gets the path to the config file
    fn config_path() -> Result<PathBuf> {
        dirs::config_dir()
            .map(|p| p.join(APP_NAME).join(CONFIG_FILE_NAME))
            .ok_or_else(|| LazyDomainError::ConfigError(
                "Could not determine config directory".to_string()
            ))
    }
}

impl Default for Config {
    fn default() -> Self {
        Self::new()
    }
}
