#!/bin/bash

# Claude Commit Message Generator - Global Version
# Automatically generates Conventional Commit messages using git diff

# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color

# Check if we're in a git repository
if ! git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
    echo -e "${RED}Not in a git repository${NC}"
    exit 1
fi

# Check if there are changes to commit
if [[ -z $(git status -s) ]]; then
    echo -e "${RED}No changes to commit${NC}"
    exit 1
fi

# Get the diff of staged changes (or all changes if nothing staged)
if [[ -n $(git diff --cached --name-only) ]]; then
    DIFF=$(git diff --cached)
    FILES=$(git diff --cached --name-only)
    echo -e "${GREEN}Analyzing staged changes...${NC}"
else
    DIFF=$(git diff)
    FILES=$(git diff --name-only)
    echo -e "${YELLOW}No staged changes. Analyzing all modified files...${NC}"
    echo -e "${YELLOW}Run 'git add' first to stage specific changes${NC}"
fi

# Get project name from git remote or directory name
PROJECT_NAME=$(basename "$(git rev-parse --show-toplevel)")
REMOTE_URL=$(git config --get remote.origin.url 2>/dev/null)
if [[ -n "$REMOTE_URL" ]]; then
    PROJECT_NAME=$(basename -s .git "$REMOTE_URL")
fi

# Create a prompt for Claude
PROMPT="Based on the following git diff from the '$PROJECT_NAME' project, generate a Conventional Commit message.

REQUIREMENTS:
1. Use Conventional Commit format: <type>(<scope>): <description>
2. Types: feat, fix, docs, style, refactor, perf, test, build, ci, chore
3. Keep first line under 72 characters
4. Use imperative mood (e.g., 'add' not 'added')
5. Include a detailed body explaining the purpose and impact
6. Note any breaking changes with 'BREAKING CHANGE:' prefix
7. Reference any issue numbers if apparent from the code

FILES CHANGED:
$FILES

GIT DIFF (showing first 500 lines):
$(echo "$DIFF" | head -n 500)

Generate ONLY the commit message, no explanations or markdown formatting."

# Call Claude API (using claude CLI)
echo -e "${GREEN}Generating commit message with Claude...${NC}"

# Save the prompt to a temporary file to avoid shell escaping issues
TEMP_PROMPT=$(mktemp)
echo "$PROMPT" > "$TEMP_PROMPT"

# Generate the commit message
COMMIT_MSG=$(claude code --no-markdown < "$TEMP_PROMPT" 2>/dev/null)

# Clean up temp file
rm "$TEMP_PROMPT"

# Check if message was generated
if [[ -z "$COMMIT_MSG" ]]; then
    echo -e "${RED}Failed to generate commit message${NC}"
    echo "Falling back to standard git commit..."
    git commit
    exit 1
fi

# Display the generated message
echo ""
echo -e "${GREEN}Generated commit message:${NC}"
echo "========================================"
echo "$COMMIT_MSG"
echo "========================================"
echo ""

# ALWAYS require explicit review
echo -e "${YELLOW}⚠️  REVIEW REQUIRED${NC}"
echo -e "${YELLOW}Please review the commit message above carefully.${NC}"
echo ""
echo -e "${YELLOW}What would you like to do?${NC}"
echo "  ${GREEN}1)${NC} Use this message AS-IS"
echo "  ${GREEN}2)${NC} EDIT this message first"
echo "  ${GREEN}3)${NC} Generate a NEW message"
echo "  ${RED}4)${NC} CANCEL (no commit)"
echo ""
read -p "Your choice [1-4]: " choice

case $choice in
    1)
        # Final confirmation before committing
        echo -e "${YELLOW}Ready to commit with the message above.${NC}"
        read -p "Confirm commit? [y/N]: " confirm
        
        if [[ "$confirm" =~ ^[Yy]$ ]]; then
            # Stage all changes if nothing is staged
            if [[ -z $(git diff --cached --name-only) ]]; then
                git add -A
            fi
            # Commit with the generated message
            git commit -m "$COMMIT_MSG"
            echo -e "${GREEN}✓ Committed successfully${NC}"
            echo -e "${YELLOW}📝 Note: Changes are committed locally only${NC}"
            echo -e "${YELLOW}   Run 'git push' manually when ready to push${NC}"
        else
            echo -e "${YELLOW}Commit cancelled${NC}"
            exit 0
        fi
        ;;
    2)
        # Save message to temp file and open in editor
        TEMP_MSG=$(mktemp)
        echo "$COMMIT_MSG" > "$TEMP_MSG"
        
        echo -e "${YELLOW}Opening editor to modify the message...${NC}"
        ${EDITOR:-vim} "$TEMP_MSG"
        
        # Show the edited message
        echo ""
        echo -e "${GREEN}Edited commit message:${NC}"
        echo "========================================"
        cat "$TEMP_MSG"
        echo "========================================"
        echo ""
        
        read -p "Commit with this edited message? [y/N]: " confirm
        
        if [[ "$confirm" =~ ^[Yy]$ ]]; then
            # Stage all changes if nothing is staged
            if [[ -z $(git diff --cached --name-only) ]]; then
                git add -A
            fi
            
            # Commit with edited message
            git commit -F "$TEMP_MSG"
            rm "$TEMP_MSG"
            echo -e "${GREEN}✓ Committed with edited message${NC}"
            echo -e "${YELLOW}📝 Note: Changes are committed locally only${NC}"
            echo -e "${YELLOW}   Run 'git push' manually when ready to push${NC}"
        else
            rm "$TEMP_MSG"
            echo -e "${YELLOW}Commit cancelled${NC}"
            exit 0
        fi
        ;;
    3)
        echo -e "${YELLOW}Regenerating commit message...${NC}"
        # Re-run the script
        exec "$0" "$@"
        ;;
    4)
        echo -e "${RED}✗ Commit cancelled by user${NC}"
        exit 0
        ;;
    *)
        echo -e "${RED}Invalid choice. Commit cancelled${NC}"
        exit 1
        ;;
esac