use serde::Deserialize;

#[derive(Debug, Clone, Deserialize)]
pub struct AppConfig {
    pub server: ServerConfig,
    pub database: DatabaseConfig,
    pub redis: RedisConfig,
    pub jwt: JwtConfig,
    pub auth: AuthConfig,
    pub log: LogConfig,
    pub cors: CorsConfig,
    pub crypto: CryptoConfig,
    pub storage: StorageConfig,
    #[serde(default)]
    pub rate_limit: RateLimitConfig,
}

#[derive(Debug, Clone, Deserialize)]
pub struct ServerConfig {
    pub host: String,
    pub port: u16,
    #[serde(default = "default_metrics_port")]
    pub metrics_port: u16,
}

fn default_metrics_port() -> u16 {
    9090
}

#[derive(Debug, Clone, Deserialize)]
pub struct DatabaseConfig {
    pub url: String,
    pub max_connections: u32,
    pub min_connections: u32,
}

#[derive(Debug, Clone, Deserialize)]
pub struct RedisConfig {
    pub url: String,
}

#[derive(Debug, Clone, Deserialize)]
pub struct JwtConfig {
    pub secret: String,
    pub access_token_ttl: String,
    pub refresh_token_ttl: String,
}

#[derive(Debug, Clone, Deserialize)]
pub struct LogConfig {
    pub level: String,
}

#[derive(Debug, Clone, Deserialize)]
pub struct AuthConfig {
    pub super_admin_password: String,
}

#[derive(Debug, Clone, Deserialize)]
pub struct CorsConfig {
    /// Comma-separated list of allowed origins.
    /// Use "*" to allow all origins (development only).
    pub allowed_origins: String,
}

#[derive(Debug, Clone, Deserialize)]
pub struct CryptoConfig {
    /// Master KEK (64 字符 hex 编码，32 字节)。用于加密保护每租户 DEK。
    /// Phase A 阶段同时作为全局数据加密密钥使用。
    pub kek: String,
}

#[derive(Debug, Clone, Deserialize)]
pub struct StorageConfig {
    /// 文件上传目录（本地存储）
    pub upload_dir: String,
    /// 单文件最大大小（如 "10MB"）
    pub max_file_size: String,
    /// 签名 URL 密钥（HMAC-SHA256）
    #[serde(default = "default_secret_key")]
    pub secret_key: String,
}

fn default_secret_key() -> String {
    #[cfg(debug_assertions)]
    {
        "dev-only-secret-key-change-in-production".to_string()
    }
    #[cfg(not(debug_assertions))]
    {
        panic!("ERP__STORAGE__SECRET_KEY 必须设置（生产环境不允许使用默认签名密钥）")
    }
}

impl StorageConfig {
    /// 解析 max_file_size 为字节数
    pub fn max_file_size_bytes(&self) -> u64 {
        let s = self.max_file_size.to_uppercase();
        if let Some(num) = s.strip_suffix("MB") {
            num.trim().parse::<u64>().unwrap_or(10) * 1024 * 1024
        } else if let Some(num) = s.strip_suffix("KB") {
            num.trim().parse::<u64>().unwrap_or(1024) * 1024
        } else if let Some(num) = s.strip_suffix("GB") {
            num.trim().parse::<u64>().unwrap_or(1) * 1024 * 1024 * 1024
        } else {
            s.parse::<u64>().unwrap_or(10 * 1024 * 1024)
        }
    }
}

#[derive(Debug, Clone, Deserialize)]
pub struct RateLimitConfig {
    /// Redis 不可达时是否拒绝请求（fail-close）。
    /// true = 安全优先，Redis 故障时返回 503。
    /// false = 可用性优先，Redis 故障时放行。
    #[serde(default = "default_fail_close")]
    pub fail_close: bool,
}

fn default_fail_close() -> bool {
    true
}

impl Default for RateLimitConfig {
    fn default() -> Self {
        Self {
            fail_close: default_fail_close(),
        }
    }
}

impl AppConfig {
    pub fn load() -> anyhow::Result<Self> {
        let config = config::Config::builder()
            .add_source(config::File::with_name("config/default"))
            .add_source(config::Environment::with_prefix("ERP").separator("__"))
            .build()?;
        let app_config: Self = config.try_deserialize()?;

        // 安全检查：禁止在生产使用默认 JWT 密钥
        if app_config.jwt.secret == "change-me-in-production" {
            tracing::warn!("⚠️  JWT 密钥使用默认值，请通过 ERP__JWT__SECRET 环境变量设置安全密钥");
        }

        Ok(app_config)
    }
}
