use std::env;
use std::path::PathBuf;

const CONFIG_BASE_PATH: &str = "provisioning/platform/config";

/// Resuelve la ruta del archivo de configuración siguiendo la jerarquía:
/// 1. Variable de entorno {SERVICE}_CONFIG (ruta explícita)
/// 2. Variable de entorno {SERVICE}_MODE + búsqueda de archivo
/// 3. Fallback a defaults
pub fn resolve_config_path(service_name: &str) -> Option<PathBuf> {
    // Priority 1: Check {SERVICE}_CONFIG env var (explicit path)
    let env_var = format!("{}_CONFIG", service_name.to_uppercase().replace('-', "_"));
    if let Ok(path) = env::var(&env_var) {
        let config_path = PathBuf::from(path);
        if config_path.exists() {
            tracing::debug!(
                "Using explicit config path from {}: {:?}",
                env_var,
                config_path
            );
            return Some(config_path);
        }
    }

    // Priority 2: Check PROVISIONING_CONFIG_DIR env var
    if let Ok(dir) = env::var("PROVISIONING_CONFIG_DIR") {
        if let Some(config) =
            super::resolver::find_config_in_dir(std::path::Path::new(&dir), service_name)
        {
            tracing::debug!("Using config from PROVISIONING_CONFIG_DIR: {:?}", config);
            return Some(config);
        }
    }

    // Priority 3: Check {SERVICE}_MODE env var + find config file
    let mode_var = format!("{}_MODE", service_name.to_uppercase().replace('-', "_"));
    let mode = env::var(&mode_var).unwrap_or_else(|_| "solo".to_string());

    if let Some(path) = find_config_file(service_name, &mode) {
        tracing::debug!(
            "Using config file for {}.{}: {:?}",
            service_name,
            mode,
            path
        );
        return Some(path);
    }

    // Fallback - no config file found
    tracing::debug!(
        "No config file found for {}.{} - using defaults",
        service_name,
        mode
    );
    None
}

/// Busca el archivo de configuración con prioridad:
/// 1. {service}.{mode}.ncl
/// 2. {service}.{mode}.toml
pub fn find_config_file(service_name: &str, mode: &str) -> Option<PathBuf> {
    let base = PathBuf::from(CONFIG_BASE_PATH);

    // Prioridad 1: .ncl
    let ncl_path = base.join(format!("{}.{}.ncl", service_name, mode));
    if ncl_path.exists() {
        tracing::trace!("Found NCL config: {:?}", ncl_path);
        return Some(ncl_path);
    }

    // Prioridad 2: .toml
    let toml_path = base.join(format!("{}.{}.toml", service_name, mode));
    if toml_path.exists() {
        tracing::trace!("Found TOML config: {:?}", toml_path);
        return Some(toml_path);
    }

    None
}

/// Obtiene la ruta base de configuración (útil para testing)
pub fn config_base_path() -> &'static str {
    CONFIG_BASE_PATH
}

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

    #[test]
    fn test_config_base_path() {
        assert_eq!(config_base_path(), "provisioning/platform/config");
    }

    #[test]
    fn test_find_config_file_priority() {
        // This test demonstrates the priority logic without requiring actual files
        // In real integration tests, we'd create temporary files
        let _ = find_config_file("test-service", "solo");
    }
}
