use secrecy::{ExposeSecret, SecretString};
use serde::Deserialize;

#[derive(Debug, Deserialize, Clone)]
pub struct AppConfig {
    pub server_port: u16,
    pub nats_addr: String,
    pub data_persistence_service_url: String,
    pub finnhub_api_url: String,
    pub finnhub_api_key: Option<SecretString>,
}

impl AppConfig {
    pub fn load() -> Result<Self, config::ConfigError> {
        let cfg = config::Config::builder()
            .add_source(config::Environment::default().separator("__"))
            .build()?;

        let cfg: Self = cfg.try_deserialize()?;

        // Deterministic validation without fallback
        if cfg.server_port == 0 {
            return Err(config::ConfigError::Message(
                "SERVER_PORT must be > 0".to_string(),
            ));
        }
        if cfg.nats_addr.trim().is_empty() {
            return Err(config::ConfigError::Message(
                "NATS_ADDR must not be empty".to_string(),
            ));
        }
        if cfg.data_persistence_service_url.trim().is_empty() {
            return Err(config::ConfigError::Message(
                "DATA_PERSISTENCE_SERVICE_URL must not be empty".to_string(),
            ));
        }
        if cfg.finnhub_api_url.trim().is_empty() {
            return Err(config::ConfigError::Message(
                "FINNHUB_API_URL must not be empty".to_string(),
            ));
        }

        Ok(cfg)
    }
}
