use std::fs;

use anyhow::{bail, Result};
use inquire::Confirm;

use crate::config::{Config, EntityKind};
use crate::registry::{packages, tools};
use crate::state::MachineState;
use crate::ui::style;

use super::exec;

/// `aimgr uninstall <name>`. Three branches:
///  - name resolves as a tool → run uninstaller (if declared), forget machine record.
///  - name resolves as a package → bail with hint to `aimgr unuse` / `aimgr purge`.
///  - name unknown but a custom tool def exists → delete the custom def file.
pub fn run(name: &str, yes: bool) -> Result<()> {
    if let Some(resolved) = tools::resolve(name)? {
        let mut machine = MachineState::load()?;
        let mut cfg = Config::load()?;

        if let Some(cmd) = &resolved.tool.uninstall {
            let ok = yes
                || Confirm::new(&format!("Run uninstaller for tool `{name}`?\n  $ {cmd}"))
                    .with_default(false)
                    .prompt()?;
            if ok {
                if !exec::trust_gate(&mut cfg, EntityKind::Tool, name, cmd)? {
                    bail!("declined");
                }
                if let Err(e) = exec::run_shell(cmd) {
                    eprintln!("{} uninstall failed (continuing): {e}", style::warn_mark());
                }
            }
        }

        cfg.remove_tool(name);
        machine.forget_tool(name);
        machine.save()?;
        cfg.save()?;
        println!("{} uninstalled `{name}`", style::ok_mark());
        return Ok(());
    }

    if packages::resolve(name)?.is_some() {
        bail!(
            "`{name}` is a package, not a tool — try `aimgr unuse {name}` or `aimgr purge {name}`"
        );
    }

    let custom = tools::custom::path_for(name)?;
    if custom.exists() {
        if !yes {
            let ok = Confirm::new(&format!("Delete custom tool def at {}?", custom.display()))
                .with_default(false)
                .prompt()?;
            if !ok {
                return Ok(());
            }
        }
        fs::remove_file(&custom)?;
        println!("{} removed {}", style::ok_mark(), custom.display());
        return Ok(());
    }

    bail!("no tool `{name}` known");
}
