use std::collections::BTreeSet;
use std::path::{Path, PathBuf};

use anyhow::{Context, Result};
use inquire::{Confirm, MultiSelect};

use crate::registry::{packages, Scope};
use crate::state::{ProjectIntent, ProjectState};
use crate::tools::Tool;
use crate::ui::style;

use super::sync;

pub fn run() -> Result<()> {
    let root = std::env::current_dir().context("getting current directory")?;
    if ProjectIntent::exists(&root) {
        let again = Confirm::new(&format!(
            "{} already has an aimgr manifest. Re-run the wizard?",
            root.display()
        ))
        .with_default(false)
        .prompt()?;
        if !again {
            return Ok(());
        }
    }

    let tools = MultiSelect::new(
        "Which AI tools does this project use?",
        vec![Tool::Claude, Tool::Codex, Tool::Cursor],
    )
    .with_default(&[0])
    .prompt()?;

    let catalog = packages::list()?;
    let names: Vec<String> = catalog
        .iter()
        .filter(|r| r.package.scope != Scope::Global)
        .map(|r| r.package.name.clone())
        .collect();
    let packages = if names.is_empty() {
        Vec::new()
    } else {
        MultiSelect::new("Which packages do you want to use?", names).prompt()?
    };

    let intent = ProjectIntent {
        tools: tools.clone(),
        packages: packages.clone(),
    };
    intent.save(&root)?;
    sync::reconcile_project(&root, false)?;
    print_summary(&root, &tools, &packages)?;
    Ok(())
}

fn print_summary(root: &Path, tools: &[Tool], packages: &[String]) -> Result<()> {
    let state = ProjectState::load(root)?;
    let wired: BTreeSet<PathBuf> = state
        .packages
        .values()
        .flat_map(|p| p.blocks.iter().map(|b| b.path.clone()))
        .collect();

    let tools_str = if tools.is_empty() {
        "claude (default)".to_string()
    } else {
        tools
            .iter()
            .map(|t| t.as_str())
            .collect::<Vec<_>>()
            .join(", ")
    };
    let packages_str = if packages.is_empty() {
        "(none)".to_string()
    } else {
        packages.join(", ")
    };

    println!();
    println!(
        "{} aimgr ready in {}",
        style::ok_mark(),
        style::bold(root.display())
    );
    println!("  {} .aimgr/aimgr.toml", style::dim("manifest:"));
    println!("  {} {tools_str}", style::dim("tools:   "));
    println!("  {} {packages_str}", style::dim("packages:"));
    if !wired.is_empty() {
        let files: Vec<String> = wired.iter().map(|p| p.display().to_string()).collect();
        println!("  {} {}", style::dim("wired:   "), files.join(", "));
    }
    println!();
    println!("{}", style::bold("next:"));
    println!("  {}  add another package", style::dim("aimgr use <name>"));
    println!("  {}  see what's in play", style::dim("aimgr status     "));
    println!(
        "  {}  re-apply after editing the manifest",
        style::dim("aimgr sync       ")
    );
    Ok(())
}
