use std::collections::HashSet;
use std::sync::Mutex;

use super::registry::LocalRegistry;

static APPLIED_PACKAGES: Mutex<Option<HashSet<String>>> = Mutex::new(None);

pub fn auto_load_packages(project_root: &str) -> Vec<String> {
    let Ok(registry) = LocalRegistry::open() else {
        return Vec::new();
    };

    let Ok(packages) = registry.auto_load_packages() else {
        return Vec::new();
    };

    if packages.is_empty() {
        return Vec::new();
    }

    let mut guard = APPLIED_PACKAGES
        .lock()
        .unwrap_or_else(std::sync::PoisonError::into_inner);
    let applied = guard.get_or_insert_with(HashSet::new);

    let mut loaded = Vec::new();

    for entry in &packages {
        let key = format!("{}@{}:{project_root}", entry.name, entry.version);
        if applied.contains(&key) {
            continue;
        }

        let Ok((manifest, content)) = registry.load_package(&entry.name, &entry.version) else {
            tracing::warn!(
                "ctxpkg auto-load: failed to load {} v{}",
                entry.name,
                entry.version
            );
            continue;
        };

        match super::loader::load_package(&manifest, &content, project_root) {
            Ok(report) => {
                applied.insert(key);
                let label = format!("{} v{}", entry.name, entry.version);
                if !report.warnings.is_empty() {
                    for w in &report.warnings {
                        tracing::warn!("ctxpkg auto-load {label}: {w}");
                    }
                }
                loaded.push(label);
            }
            Err(e) => {
                tracing::warn!(
                    "ctxpkg auto-load: apply failed for {} v{}: {e}",
                    entry.name,
                    entry.version
                );
            }
        }
    }

    loaded
}
