use std::collections::HashMap;
use std::fs;

pub const EDITORS: &[&str] = &["nvim", "vim", "nano", "hx", "helix", "emacs", "vi"];
pub const VIEWERS: &[&str] = &["cat", "bat", "less", "more", "head", "tail", "fzf"];

pub fn load_aliases() -> HashMap<String, String> {
    let home = std::env::var("HOME").unwrap_or_default();
    let path = std::path::Path::new(&home).join(".config/recap/aliases.toml");

    if !path.exists() {
        return default_aliases();
    }

    let content = fs::read_to_string(&path).unwrap_or_default();
    let parsed: toml::Value = content
        .parse()
        .unwrap_or(toml::Value::Table(Default::default()));

    let mut map = default_aliases();
    if let Some(aliases) = parsed.get("aliases").and_then(|v| v.as_table()) {
        for (k, v) in aliases {
            if let Some(s) = v.as_str() {
                map.insert(k.clone(), s.to_string());
            }
        }
    }
    map
}

pub fn default_aliases() -> HashMap<String, String> {
    let mut m = HashMap::new();
    for (k, v) in [
        ("g", "git"),
        ("ga", "git add"),
        ("gc", "git commit"),
        ("gp", "git push"),
        ("gl", "git pull"),
        ("gst", "git status"),
        ("gd", "git diff"),
        ("gco", "git checkout"),
        ("gb", "git branch"),
        ("nv", "nvim"),
        ("v", "vim"),
        ("cb", "cargo build"),
        ("cr", "cargo run"),
        ("ct", "cargo test"),
    ] {
        m.insert(k.to_string(), v.to_string());
    }
    m
}

pub fn classify<'a>(cmd: &'a str, aliases: &'a HashMap<String, String>) -> &'a str {
    let bin = cmd.split_whitespace().next().unwrap_or("");
    let resolved = aliases.get(bin).map(|s| s.as_str()).unwrap_or(bin);
    if EDITORS.contains(&resolved) {
        "edit"
    } else if VIEWERS.contains(&resolved) {
        "view"
    } else {
        "run"
    }
}

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

    #[test]
    fn classify_editor() {
        let aliases = default_aliases();
        assert_eq!(classify("nvim src/main.rs", &aliases), "edit");
        assert_eq!(classify("vim Cargo.toml", &aliases), "edit");
    }

    #[test]
    fn classify_viewer() {
        let aliases = default_aliases();
        assert_eq!(classify("cat README.md", &aliases), "view");
        assert_eq!(classify("less src/main.rs", &aliases), "view");
    }

    #[test]
    fn classify_run() {
        let aliases = default_aliases();
        assert_eq!(classify("cargo build", &aliases), "run");
        assert_eq!(classify("git status", &aliases), "run");
    }

    #[test]
    fn classify_alias_resolves_to_editor() {
        let aliases = default_aliases();
        assert_eq!(classify("nv src/main.rs", &aliases), "edit");
    }
}
