use clap::Parser;
use std::process::Command;

#[derive(Parser)]
#[command(name = "gai", about = "Git operations for AI workflow")]
struct Cli {
    branch: String,
    message: String,

    #[arg(long, help = "Stay on the new branch instead of switching back")]
    stay: bool,
}

fn run(args: &[&str]) -> Result<String, String> {
    let output = Command::new("git")
        .args(args)
        .output()
        .map_err(|e| format!("failed to run git {}: {e}", args.join(" ")))?;

    if !output.status.success() {
        let stderr = String::from_utf8_lossy(&output.stderr);
        return Err(stderr.trim().to_string());
    }

    Ok(String::from_utf8_lossy(&output.stdout).trim().to_string())
}

fn current_branch() -> Result<String, String> {
    run(&["branch", "--show-current"])
}

fn has_changes() -> Result<bool, String> {
    let output = run(&["status", "--porcelain"])?;
    Ok(!output.is_empty())
}

fn main() {
    let cli = Cli::parse();
    let original = current_branch().unwrap_or_else(|e| {
        eprintln!("error: could not determine current branch: {e}");
        std::process::exit(1);
    });

    if !has_changes().unwrap_or(true) {
        eprintln!("error: no changes to commit");
        std::process::exit(1);
    }

    run(&["add", "-A"]).unwrap_or_else(|e| {
        eprintln!("error: git add failed: {e}");
        std::process::exit(1);
    });

    run(&["checkout", "-b", &cli.branch]).unwrap_or_else(|e| {
        eprintln!("error: could not create branch '{}': {e}", cli.branch);
        std::process::exit(1);
    });

    run(&["commit", "-m", &cli.message]).unwrap_or_else(|e| {
        eprintln!("error: commit failed: {e}");
        let _ = run(&["checkout", &original]);
        std::process::exit(1);
    });

    if cli.stay {
        println!("committed on '{}'", cli.branch);
    } else {
        run(&["checkout", &original]).unwrap_or_else(|e| {
            eprintln!("error: could not switch back to '{}': {e}", original);
            std::process::exit(1);
        });
        println!(
            "committed on '{}', switched back to '{}'",
            cli.branch, original
        );
    }
}
