xgit 0.2.6

A enhanced AI-powered Git tool
use super::git_passthrough::git_passthrough;
use crate::{ai, git::GitRepo};
use console::style;
use std::fs;
use std::process::Command;

pub fn handle_commit(args: &[String]) -> Result<(), Box<dyn std::error::Error>> {
    // Check if user provided commit message or other flags that should bypass interactive mode
    let has_message_flag = args.iter().any(|arg| {
        arg == "-m"
            || arg == "--message"
            || arg == "-F"
            || arg == "--file"
            || arg == "-C"
            || arg == "--reuse-message"
            || arg == "-c"
            || arg == "--reedit-message"
            || arg == "--fixup"
            || arg == "--squash"
            || arg.starts_with("-m=")
            || arg.starts_with("--message=")
    });

    // If user provided message flags or other args, use passthrough mode
    if has_message_flag || !args.is_empty() {
        return passthrough_commit(args);
    }

    // Otherwise, use AI-assisted commit
    ai_commit()
}

fn passthrough_commit(args: &[String]) -> Result<(), Box<dyn std::error::Error>> {
    git_passthrough("commit", args)
}

fn ai_commit() -> Result<(), Box<dyn std::error::Error>> {
    // Check if there are staged changes
    let git_repo = GitRepo::open(".")?;

    if !git_repo.has_staged_changes()? {
        eprintln!(
            "{} No changes staged for commit.",
            style("").yellow().bold()
        );
        return Ok(());
    }

    // Get the diff for AI processing
    let diff_text = git_repo.diff_staged()?;

    // Try to generate commit message with Claude
    let generated_message = ai::generate_commit_message(&diff_text)?;

    if let Some(message) = generated_message {
        // Write generated message to a temporary file with comment
        let temp_file = "/tmp/gitx_commit_template";
        let template_content = format!(
            "{message}\n\n# Generated by gitx with Claude AI\n# Edit the message above and save to commit"
        );
        fs::write(temp_file, &template_content)?;

        // Use git commit with template
        let mut cmd = Command::new("git");
        cmd.arg("commit");
        cmd.arg("-t");
        cmd.arg(temp_file);
        cmd.arg("--allow-empty-message");

        let status = cmd.status()?;

        // Clean up
        let _ = fs::remove_file(temp_file);

        if !status.success() {
            std::process::exit(status.code().unwrap_or(1));
        }
    } else {
        // Fallback to normal git commit
        let status = Command::new("git").arg("commit").status()?;

        if !status.success() {
            std::process::exit(status.code().unwrap_or(1));
        }
    }

    Ok(())
}