#!/bin/bash

# AI Commit Message Generator using OpenAI API
# Usage: ./scripts/ai-commit.sh [--dry-run|--generate-only|--help]

set -e

# Print help and exit if --help is passed
if [[ "$1" == "--help" ]]; then
    echo "AI Commit Message Generator using OpenAI API"
    echo "Usage: ai-commit [--dry-run|--generate-only|--help]"
    echo "  --dry-run         Show the generated commit message but do not commit"
    echo "  --generate-only   Output only the commit message (for hooks)"
    echo "  --help            Show this help message and exit"
    exit 0
fi

# Check if inside a git repository
if ! git rev-parse --git-dir > /dev/null 2>&1; then
    echo "❌ Error: Not inside a git repository. Please run 'git init' first."
    exit 1
fi

# Support for --generate-only flag (for use in hooks)
GENERATE_ONLY=false
if [ "$1" = "--generate-only" ]; then
    GENERATE_ONLY=true
    shift
fi

# Load AI prompts configuration
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
CONFIG_DIR="$(dirname "$SCRIPT_DIR")/configs"
if [ -f "$CONFIG_DIR/ai-prompts.conf" ]; then
    source "$CONFIG_DIR/ai-prompts.conf"
else
    echo "❌ Error: AI prompts configuration not found at $CONFIG_DIR/ai-prompts.conf"
    exit 1
fi

# Load exclusion patterns from config
EXCLUDE_PATTERNS=( $AI_COMMIT_EXCLUDE )

# Configuration (using values from ai-prompts.conf)
OPENAI_API_URL="$OPENAI_API_URL"
MODEL="$OPENAI_MODEL"
MAX_TOKENS="$OPENAI_MAX_TOKENS"

# Check if API key is provided
if [ -z "$OPENAI_API_KEY" ]; then
    echo "❌ Error: OPENAI_API_KEY environment variable not set"
    echo "💡 Set it with: export OPENAI_API_KEY='your-api-key-here'"
    exit 1
fi

# Check for staged changes
if git diff --cached --quiet; then
    if [ "$GENERATE_ONLY" = false ]; then
        echo "❌ No staged changes found. Use 'git add' first."
    fi
    exit 1
fi

if [ "$GENERATE_ONLY" = false ]; then
    echo "🔍 Analyzing staged changes..."
fi

# Helper to build grep -v pattern for exclusions
build_exclude_grep() {
  local args=""
  for pat in "${EXCLUDE_PATTERNS[@]}"; do
    args+="| grep -v '^${pat//\//\/}' "
  done
  echo "$args"
}

# Get filtered file list
ALL_FILES=$(git diff --cached --name-only)
FILTERED_FILES="$ALL_FILES"

# Apply exclusion patterns if any exist
if [ ${#EXCLUDE_PATTERNS[@]} -gt 0 ]; then
    for pat in "${EXCLUDE_PATTERNS[@]}"; do
        if [ -n "$pat" ]; then
            FILTERED_FILES=$(echo "$FILTERED_FILES" | grep -v "^$pat" || true)
        fi
    done
fi

FILES=$(echo "$FILTERED_FILES" | tr '\n' ', ' | sed 's/,$//')

# Create a comprehensive change summary
FILE_COUNT=$(echo "$FILTERED_FILES" | wc -l)
NEW_FILES=$(git diff --cached --name-status | grep "^A" | wc -l)
MODIFIED_FILES=$(git diff --cached --name-status | grep "^M" | wc -l)
DELETED_FILES=$(git diff --cached --name-status | grep "^D" | wc -l)

# Get comprehensive diff with smart truncation
# Include file stats and a representative sample of changes
DIFF_STATS=$(git diff --cached --stat -- $FILTERED_FILES)
DIFF_SAMPLE=$(git diff --cached --no-color -- $FILTERED_FILES | head -200)

# Combine stats and sample for AI context
DIFF=$(cat << EOF
File Summary: $FILE_COUNT files changed
- New files: $NEW_FILES
- Modified files: $MODIFIED_FILES  
- Deleted files: $DELETED_FILES

Files: $FILES

Change Statistics:
$DIFF_STATS

Representative Changes:
$DIFF_SAMPLE
EOF
)

# Use the centralized prompt from config
PROMPT=$(eval echo "\"$AI_COMMIT_PROMPT\"")

# Prepare JSON payload (safer escaping)
JSON_PAYLOAD=$(cat << EOF
{
    "model": "$MODEL",
    "messages": [
        {
            "role": "user", 
            "content": $(echo "$PROMPT" | jq -R -s .)
        }
    ],
    "max_tokens": $MAX_TOKENS,
    "temperature": $OPENAI_TEMPERATURE
}
EOF
)

if [ "$GENERATE_ONLY" = false ]; then
    echo "🤖 Generating commit message..."
fi

# Call OpenAI API
RESPONSE=$(curl -s -X POST "$OPENAI_API_URL" \
    -H "Content-Type: application/json" \
    -H "Authorization: Bearer $OPENAI_API_KEY" \
    -d "$JSON_PAYLOAD")

# Check for API errors
if echo "$RESPONSE" | jq -e '.error' >/dev/null 2>&1; then
    echo "❌ OpenAI API Error:"
    echo "$RESPONSE" | jq -r '.error.message'
    exit 1
fi

# Extract commit message
COMMIT_MSG=$(echo "$RESPONSE" | jq -r '.choices[0].message.content' | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')

if [ -z "$COMMIT_MSG" ] || [ "$COMMIT_MSG" = "null" ]; then
    echo "❌ Failed to generate commit message"
    exit 1
fi

# Validate length - check subject line only (first line)
SUBJECT_LINE=$(echo "$COMMIT_MSG" | head -n1)
SUBJECT_LENGTH=${#SUBJECT_LINE}
MSG_LENGTH=${#COMMIT_MSG}

# Generate-only mode (for hooks) - output just the message
if [ "$GENERATE_ONLY" = true ]; then
    echo "$COMMIT_MSG"
    exit 0
fi

# For interactive mode, show the message details
echo "📝 Generated message (${MSG_LENGTH} chars total, ${SUBJECT_LENGTH} chars subject): $COMMIT_MSG"

if [ $SUBJECT_LENGTH -gt $MAX_COMMIT_LENGTH ]; then
    echo "⚠️  Warning: Subject line exceeds $MAX_COMMIT_LENGTH characters"
elif [ $SUBJECT_LENGTH -gt $WARN_COMMIT_LENGTH ]; then
    echo "⚠️  Note: Subject line is approaching the $MAX_COMMIT_LENGTH character limit"
fi

# Dry run option
if [ "$1" = "--dry-run" ]; then
    echo "🏃 Dry run mode - not committing"
    exit 0
fi

# Confirm and commit
echo ""
read -p "🚀 Proceed with commit? (Y/n): " confirm

if [[ $confirm =~ ^[Nn]$ ]]; then
    echo "❌ Commit cancelled"
    echo "💡 You can copy the message: $COMMIT_MSG"
else
    git commit -m "$COMMIT_MSG"
    echo "✅ Committed successfully!"
fi
