use std::{
    env,
    path::PathBuf,
    process::Command,
};

use anyhow::{
    Context,
    Result,
};

fn main() -> Result<()> {
    let task = env::args().nth(1);
    match task.as_deref() {
        | Some("clean") => clean()?,
        | Some(task) => {
            eprintln!("Unknown task: {}", task);
            print_help();
            std::process::exit(1);
        },
        | None => {
            print_help();
            std::process::exit(1);
        },
    }
    Ok(())
}

fn print_help() {
    eprintln!(
        r#"
Tasks:
  clean         Clean all build artifacts across all projects
    "#
    );
}

fn clean() -> Result<()> {
    let root = project_root();

    println!("🧹 Cleaning Storybook workspace...\n");

    // Clean Rust projects
    println!("  Cleaning Rust artifacts...");
    run_command(&["cargo", "clean"], &root)?;

    // Clean tree-sitter-storybook
    let tree_sitter_dir = root.join("tree-sitter-storybook");
    if tree_sitter_dir.exists() {
        println!("  Cleaning tree-sitter-storybook...");

        // Remove node_modules
        let node_modules = tree_sitter_dir.join("node_modules");
        if node_modules.exists() {
            println!("    Removing node_modules/");
            std::fs::remove_dir_all(&node_modules)
                .context("Failed to remove tree-sitter-storybook/node_modules")?;
        }

        // Remove target directory
        let target = tree_sitter_dir.join("target");
        if target.exists() {
            println!("    Removing target/");
            std::fs::remove_dir_all(&target)
                .context("Failed to remove tree-sitter-storybook/target")?;
        }

        // Remove Cargo.lock
        let cargo_lock = tree_sitter_dir.join("Cargo.lock");
        if cargo_lock.exists() {
            println!("    Removing Cargo.lock");
            std::fs::remove_file(&cargo_lock)
                .context("Failed to remove tree-sitter-storybook/Cargo.lock")?;
        }

        // Remove build artifacts
        let build_dir = tree_sitter_dir.join("build");
        if build_dir.exists() {
            println!("    Removing build/");
            std::fs::remove_dir_all(&build_dir)
                .context("Failed to remove tree-sitter-storybook/build")?;
        }
    }

    // Clean zed-storybook
    let zed_dir = root.join("zed-storybook");
    if zed_dir.exists() {
        println!("  Cleaning zed-storybook...");

        // Remove grammars directory (build artifact)
        let grammars = zed_dir.join("grammars");
        if grammars.exists() {
            println!("    Removing grammars/");
            std::fs::remove_dir_all(&grammars)
                .context("Failed to remove zed-storybook/grammars")?;
        }

        // Remove extension.wasm
        let wasm = zed_dir.join("extension.wasm");
        if wasm.exists() {
            println!("    Removing extension.wasm");
            std::fs::remove_file(&wasm).context("Failed to remove zed-storybook/extension.wasm")?;
        }
    }

    // Clean mdbook artifacts
    let docs_dir = root.join("docs");
    if docs_dir.exists() {
        println!("  Cleaning mdbook artifacts...");

        let book_dir = docs_dir.join("book");
        if book_dir.exists() {
            println!("    Removing docs/book/");
            std::fs::remove_dir_all(&book_dir).context("Failed to remove docs/book")?;
        }
    }

    println!("\n✨ Clean complete!");
    Ok(())
}

fn run_command(cmd: &[&str], cwd: &PathBuf) -> Result<()> {
    let mut command = Command::new(cmd[0]);
    command.args(&cmd[1..]).current_dir(cwd);

    let status = command
        .status()
        .with_context(|| format!("Failed to run command: {:?}", cmd))?;

    if !status.success() {
        anyhow::bail!("Command failed: {:?}", cmd);
    }

    Ok(())
}

fn project_root() -> PathBuf {
    PathBuf::from(env!("CARGO_MANIFEST_DIR"))
        .parent()
        .unwrap()
        .to_path_buf()
}
