use forge::signal::compactor;
use once_cell::sync::Lazy;
use regex::Regex;

// Download progress bars and reshim noise
static PROGRESS_RE: Lazy<Regex> = Lazy::new(|| {
    Regex::new(r"(?m)^(Downloading|Extracting|Installing|Verifying|Reshimming|Running) [^\n]+\n?")
        .unwrap()
});

pub fn compress_mise(subcmd: &str, raw: &str) -> String {
    let sub = subcmd.trim();
    match sub {
        "install" | "i" => compress_install(raw),
        "use" | "u" => compress_use(raw),
        "run" | "exec" | "x" => compactor::normalise(raw), // task output — passthrough
        "ls" | "list" | "current" | "latest" | "outdated" => compactor::normalise(raw),
        _ => compress_install(raw),
    }
}

fn compress_install(raw: &str) -> String {
    let cleaned = compactor::normalise(raw);
    let s = PROGRESS_RE.replace_all(&cleaned, "");

    // Keep: "mise tool@version installed" confirmation lines + errors
    let kept: Vec<&str> = s
        .lines()
        .filter(|l| {
            let t = l.trim();
            t.is_empty()
                || t.starts_with("mise")
                || t.contains("installed")
                || t.contains("already installed")
                || t.contains("error")
                || t.contains("failed")
        })
        .collect();

    let out = compactor::collapse_blanks(&kept.join("\n"));
    if out.trim().is_empty() {
        "(mise install: completed)".to_string()
    } else {
        out
    }
}

fn compress_use(raw: &str) -> String {
    let cleaned = compactor::normalise(raw);
    let s = PROGRESS_RE.replace_all(&cleaned, "");

    // Keep: "mise: set tool@version" confirmation + .mise.toml update lines
    let kept: Vec<&str> = s
        .lines()
        .filter(|l| {
            let t = l.trim();
            t.is_empty()
                || t.starts_with("mise")
                || t.contains(".mise.toml")
                || t.contains("set ")
                || t.contains("error")
        })
        .collect();

    compactor::collapse_blanks(&kept.join("\n"))
}

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

    #[test]
    fn install_strips_download_progress() {
        let raw = "Downloading node 20.0.0...\nExtracting node 20.0.0...\nInstalling node 20.0.0...\nmise node@20.0.0 installed\n";
        let out = compress_mise("install", raw);
        assert!(!out.contains("Downloading"), "{out}");
        assert!(out.contains("installed") || out.contains("node"), "{out}");
    }

    #[test]
    fn run_is_passthrough() {
        let raw = "hello from task\ndone\n";
        let out = compress_mise("run", raw);
        assert!(out.contains("hello"), "{out}");
    }

    #[test]
    fn use_keeps_config_update() {
        let raw = "Reshimming mise...\nmise: set node@20.0.0 in .mise.toml\n";
        let out = compress_mise("use", raw);
        assert!(!out.contains("Reshimming"), "{out}");
        assert!(out.contains(".mise.toml") || out.contains("set"), "{out}");
    }
}
