use serde::Deserialize;
use config::Config;

#[derive(Deserialize, Debug)]
pub struct AppConfig {
    pub server_port: u16,
    pub nats_addr: String,
    pub data_persistence_service_url: String,
    pub provider_services: Vec<String>,
}

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

        let server_port: u16 = cfg.get::<u16>("server_port")?;
        let nats_addr: String = cfg.get::<String>("nats_addr")?;
        let data_persistence_service_url: String = cfg.get::<String>("data_persistence_service_url")?;

        // Parse provider_services deterministically:
        // 1) prefer array from env (e.g., PROVIDER_SERVICES__0, PROVIDER_SERVICES__1, ...)
        // 2) fallback to explicit JSON in PROVIDER_SERVICES
        let provider_services: Vec<String> = if let Ok(arr) = cfg.get_array("provider_services") {
            let mut out: Vec<String> = Vec::with_capacity(arr.len());
            for v in arr {
                let s = v.into_string().map_err(|e| {
                    config::ConfigError::Message(format!("provider_services must be strings: {}", e))
                })?;
                out.push(s);
            }
            out
        } else {
            let json = cfg.get_string("provider_services")?;
            serde_json::from_str::<Vec<String>>(&json).map_err(|e| {
                config::ConfigError::Message(format!(
                    "Invalid JSON for provider_services: {}",
                    e
                ))
            })?
        };

        Ok(Self {
            server_port,
            nats_addr,
            data_persistence_service_url,
            provider_services,
        })
    }
}
