//! 应用配置模块
//!
//! 支持多环境配置加载，优先级：环境变量 > 环境配置 > 默认配置

use serde::Deserialize;
use std::path::PathBuf;

#[derive(Debug, Deserialize, Clone)]
pub struct AppConfig {
    pub database_url: String,
    pub wechat_appid: String,
    pub wechat_secret: String,
    pub jwt_secret: String,
    pub ssl_key_path: String,
    pub ssl_cert_path: String,
    pub rust_log: String,
    pub environment: String,
    pub free_user_data_limit: i32,
    pub server_host: String,
    #[serde(rename = "server_ports")]
    pub server_ports: Vec<u16>,
}

impl AppConfig {
    pub fn load() -> Result<Self, String> {
        let env = std::env::var("APP_ENV").unwrap_or_else(|_| "development".into());

        let manifest_dir = std::env::var("CARGO_MANIFEST_DIR")
            .map(PathBuf::from)
            .unwrap_or_else(|_| std::env::current_dir().unwrap());

        let config_dir = manifest_dir.join("config");

        let default_path = config_dir.join("default.toml");
        let env_path = config_dir.join(&format!("{}.toml", env));

        let mut settings = toml::Table::new();

        // 1. 加载 default.toml
        if default_path.exists() {
            let content = std::fs::read_to_string(&default_path)
                .map_err(|e| format!("读取 default.toml 失败: {}", e))?;
            let parsed: toml::Table =
                toml::from_str(&content).map_err(|e| format!("解析 default.toml 失败: {}", e))?;
            settings.extend(parsed);
        } else {
            return Err(format!("配置文件不存在: {}", default_path.display()));
        }

        // 2. 合并环境配置（覆盖默认值）
        if env_path.exists() {
            let content = std::fs::read_to_string(&env_path)
                .map_err(|e| format!("读取 {}.toml 失败: {}", env, e))?;
            let parsed: toml::Table =
                toml::from_str(&content).map_err(|e| format!("解析 {}.toml 失败: {}", env, e))?;
            settings.extend(parsed);
        }

        // 3. 从环境变量加载（最高优先级）
        if let Ok(val) = std::env::var("APP_DATABASE_URL") {
            settings.insert("database_url".into(), toml::Value::String(val));
        }
        if let Ok(val) = std::env::var("APP_JWT_SECRET") {
            settings.insert("jwt_secret".into(), toml::Value::String(val));
        }
        if let Ok(val) = std::env::var("APP_WECHAT_APPID") {
            settings.insert("wechat_appid".into(), toml::Value::String(val));
        }
        if let Ok(val) = std::env::var("APP_WECHAT_SECRET") {
            settings.insert("wechat_secret".into(), toml::Value::String(val));
        }
        if let Ok(val) = std::env::var("APP_RUST_LOG") {
            settings.insert("rust_log".into(), toml::Value::String(val));
        }
        if let Ok(val) = std::env::var("APP_FREE_USER_DATA_LIMIT") {
            if let Ok(num) = val.parse::<i64>() {
                settings.insert("free_user_data_limit".into(), toml::Value::Integer(num));
            }
        }

        let app_config: AppConfig = toml::from_str(&settings.to_string())
            .map_err(|e| format!("配置反序列化失败: {}", e))?;

        tracing::info!("配置加载成功，环境={}", app_config.environment);

        Ok(app_config)
    }

    pub fn database_url(&self) -> &str {
        &self.database_url
    }

    pub fn rust_log(&self) -> &str {
        &self.rust_log
    }

    pub fn is_production(&self) -> bool {
        self.environment == "production"
    }
}
