use super::{
    abuse::AbuseConfig, auth::AuthConfig, database::DatabaseConfig, email::EmailConfig,
    redis::RedisConfig, server::ServerConfig, smtp::SmtpConfig,
};
use config::{Config, ConfigError, Environment, File};
use serde::Deserialize;
use std::path::PathBuf;

// 导入 redis 默认值函数（使用完整路径）
use crate::config::redis::default_redis_host;

#[derive(Debug, Deserialize, Clone)]
pub struct AppConfig {
    pub server: ServerConfig,
    pub database: DatabaseConfig,
    pub auth: AuthConfig,
    pub redis: RedisConfig,
    #[serde(default)]
    pub email: EmailConfig,
    #[serde(default)]
    pub smtp: SmtpConfig,
    #[serde(default)]
    pub abuse: AbuseConfig,
}

impl AppConfig {
    /// 加载配置（支持 CLI 覆盖）
    ///
    /// 如果 config_path 为 None，则仅使用环境变量和默认值
    pub fn load_with_overrides(
        cli_config_path: Option<std::path::PathBuf>,
        overrides: crate::cli::ConfigOverrides,
        _environment: &str,
    ) -> Result<Self, ConfigError> {
        // 使用 ConfigBuilder 设置配置
        let mut builder = Config::builder();

        // 如果提供了配置文件，先加载它
        if let Some(config_path) = cli_config_path {
            if !config_path.exists() {
                tracing::error!("Configuration file not found: {}", config_path.display());
                return Err(ConfigError::NotFound(
                    config_path.to_string_lossy().to_string(),
                ));
            }
            tracing::info!("Loading configuration from: {}", config_path.display());
            builder = builder.add_source(File::from(config_path));
        } else {
            tracing::info!("No configuration file found, using environment variables and defaults");
            tracing::warn!("⚠️  没有找到配置文件，将使用 SQLite 作为默认数据库");
            tracing::warn!("   默认数据库路径: db.sqlite3");
            tracing::warn!("   如需使用其他数据库，请创建配置文件或设置环境变量");

            // 直接使用 set_default 设置默认值
            // 注意：这些值会被环境变量覆盖
            builder = builder.set_default("server.host", default_server_host())?;
            builder = builder.set_default("server.port", default_server_port())?;
            builder = builder.set_default("server.request_timeout_seconds", 30)?;
            builder = builder.set_default("server.max_body_bytes", 1048576)?;
            builder = builder.set_default("server.concurrency_limit", 256)?;
            builder = builder.set_default("server.rate_limit_per_minute", 120)?;
            builder = builder.set_default("server.cors_origins", vec!["http://localhost:3000"])?;

            // 设置 database 默认值（使用 SQLite 作为默认数据库）
            builder = builder.set_default("database.database_type", "sqlite")?;
            builder = builder.set_default("database.path", "db.sqlite3")?;
            builder = builder.set_default("database.max_connections", 10)?;

            // 设置 auth 默认值
            builder = builder.set_default("auth.jwt_secret", default_jwt_secret())?;
            builder = builder.set_default("auth.access_token_expiration_minutes", 15)?;
            builder = builder.set_default("auth.refresh_token_expiration_days", 7)?;

            // 设置 redis 默认值
            builder = builder.set_default("redis.host", default_redis_host())?;
            builder = builder.set_default("redis.enabled", false)?;
            builder = builder.set_default("redis.port", 6379)?;
            builder = builder.set_default("redis.db", 0)?;
            builder = builder.set_default("email.enabled", false)?;
        }

        // 添加环境变量源（会覆盖配置文件的值）
        builder = builder.add_source(environment_source());

        // 应用 CLI 覆盖（仅 Web 服务器参数）
        if let Some(host) = overrides.host {
            builder = builder.set_override("server.host", host)?;
        }
        if let Some(port) = overrides.port {
            builder = builder.set_override("server.port", port)?;
        }

        let settings = builder.build()?;
        let config: AppConfig = settings.try_deserialize()?;

        validate_security(&config, _environment)?;

        // 安全警告：检查是否使用了默认的 JWT 密钥
        if config.auth.jwt_secret == "change-this-to-a-strong-secret-key-in-production" {
            tracing::warn!("⚠️  警告：正在使用不安全的默认 JWT 密钥！");
            tracing::warn!("  请通过环境变量 AUTH_JWT_SECRET 或配置文件设置强密钥");
            tracing::warn!("  示例：AUTH_JWT_SECRET=your-secure-random-string-here");
        }

        // 验证数据库配置
        if let Err(e) = config.database.validate() {
            tracing::error!("数据库配置无效: {}", e);
            return Err(ConfigError::Message(format!("数据库配置无效: {}", e)));
        }

        Ok(config)
    }

    /// 从指定路径加载配置
    pub fn load_from_path(path: &str) -> Result<Self, ConfigError> {
        tracing::info!("Loading configuration from: {}", path);

        let settings = Config::builder()
            .add_source(File::from(PathBuf::from(path)))
            .add_source(environment_source())
            .build()?;

        let config: AppConfig = settings.try_deserialize()?;

        // 安全警告：检查是否使用了默认的 JWT 密钥
        if config.auth.jwt_secret == "change-this-to-a-strong-secret-key-in-production" {
            tracing::warn!("⚠️  警告：正在使用不安全的默认 JWT 密钥！");
            tracing::warn!("  请通过环境变量 AUTH_JWT_SECRET 或配置文件设置强密钥");
            tracing::warn!("  示例：AUTH_JWT_SECRET=your-secure-random-string-here");
        }

        // 验证数据库配置
        if let Err(e) = config.database.validate() {
            tracing::error!("数据库配置无效: {}", e);
            return Err(ConfigError::Message(format!("数据库配置无效: {}", e)));
        }

        Ok(config)
    }
}

fn environment_source() -> Environment {
    Environment::default()
        .separator("__")
        .try_parsing(true)
        .list_separator(",")
        .with_list_parse_key("server.cors_origins")
        .with_list_parse_key("smtp.local_domains")
        .with_list_parse_key("abuse.honeypot_addresses")
}

fn validate_security(config: &AppConfig, environment: &str) -> Result<(), ConfigError> {
    if environment.eq_ignore_ascii_case("production") {
        if config.auth.jwt_secret == default_jwt_secret()
            || config.auth.jwt_secret.contains("CHANGE_ME")
            || config.auth.jwt_secret.len() < 32
        {
            return Err(ConfigError::Message("生产环境禁止使用默认 JWT 密钥".into()));
        }
        if config.smtp.body_encryption_key.len() != 32
            || config.smtp.body_encryption_key.contains("CHANGE_ME")
        {
            return Err(ConfigError::Message(
                "生产环境必须配置 32 字节 SMTP 正文加密密钥".into(),
            ));
        }
        if !config.auth.bootstrap_admin_email.is_empty()
            && (config.auth.invite_code.len() < 16 || config.auth.invite_code.contains("CHANGE_ME"))
        {
            return Err(ConfigError::Message(
                "配置首个管理员邮箱时，生产环境必须同时设置至少 16 字符的邀请码".into(),
            ));
        }
        if config
            .server
            .cors_origins
            .iter()
            .any(|origin| origin == "*")
        {
            return Err(ConfigError::Message(
                "生产环境禁止使用通配 CORS 来源".into(),
            ));
        }
    }
    Ok(())
}

// 默认值函数（复用）
fn default_server_host() -> String {
    "127.0.0.1".to_string()
}

fn default_server_port() -> u16 {
    3000
}

fn default_jwt_secret() -> String {
    "change-this-to-a-strong-secret-key-in-production".to_string()
}

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

    #[test]
    fn production_rejects_default_secret_and_wildcard_cors() {
        let mut config = AppConfig::load_from_path("config/development.toml").unwrap();
        config.auth.jwt_secret = default_jwt_secret();
        assert!(validate_security(&config, "production").is_err());
        config.auth.jwt_secret = "a-production-secret-with-32-bytes".into();
        config.smtp.body_encryption_key = "0123456789abcdef0123456789abcdef".into();
        config.auth.bootstrap_admin_email = String::new();
        config.server.cors_origins = vec!["*".into()];
        assert!(validate_security(&config, "production").is_err());
    }

    #[test]
    fn development_accepts_safe_defaults() {
        let config = AppConfig::load_from_path("config/development.toml").unwrap();
        assert!(validate_security(&config, "development").is_ok());
    }
}
