use super::*;

impl Scaffolder {
    /// Generate commit-msg git hook content
    pub(super) fn generate_commit_msg_hook(&self) -> String {
        r#"#!/bin/bash
# AIDA commit-msg hook - Validates AI attribution in commit messages
# Generated by AIDA scaffolding
# trace:FR-0226 | ai:claude:high

COMMIT_MSG_FILE="$1"
COMMIT_MSG=$(cat "$COMMIT_MSG_FILE")

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

# Check if commit message contains AI attribution tag [AI:tool] or [AI:tool:conf]
# [AI:tool] implies high confidence, [AI:tool:med] or [AI:tool:low] for others
AI_TAG_PATTERN='\[AI:[a-zA-Z]+(:(med|low))?\]'

# Check for files with trace comments in this commit
STAGED_FILES=$(git diff --cached --name-only)
HAS_TRACE_FILES=false

# Files to exclude from trace detection (data files, not source code)
EXCLUDE_PATTERNS="requirements.yaml requirements.yaml.lock requirements.db"

for file in $STAGED_FILES; do
    # Skip excluded files
    skip=false
    for pattern in $EXCLUDE_PATTERNS; do
        if [[ "$file" == *"$pattern"* ]]; then
            skip=true
            break
        fi
    done
    [ "$skip" = true ] && continue

    if [ -f "$file" ]; then
        if grep -q "trace:[A-Z]*-[0-9]*" "$file" 2>/dev/null; then
            HAS_TRACE_FILES=true
            break
        fi
    fi
done

# If staged files have trace comments but commit lacks AI tag, warn
if [ "$HAS_TRACE_FILES" = true ]; then
    if ! echo "$COMMIT_MSG" | grep -qE "$AI_TAG_PATTERN"; then
        echo -e "${YELLOW}⚠ Warning: Commit includes files with AI trace comments but no [AI:tool] tag in commit message.${NC}"
        echo -e "${YELLOW}  Consider using format: [AI:claude] feat: description${NC}"
        echo -e "${YELLOW}  Confidence: [AI:tool] = high (implied), [AI:tool:med] = medium, [AI:tool:low] = low${NC}"
        echo ""
    fi
fi

# Check for Trace: references in commit message matching staged file traces
if [ "$HAS_TRACE_FILES" = true ]; then
    # Extract spec IDs from staged files (excluding data files)
    SPEC_IDS=""
    for file in $STAGED_FILES; do
        # Skip excluded files
        skip=false
        for pattern in $EXCLUDE_PATTERNS; do
            if [[ "$file" == *"$pattern"* ]]; then
                skip=true
                break
            fi
        done
        [ "$skip" = true ] && continue

        if [ -f "$file" ]; then
            FILE_SPECS=$(grep -oE "trace:[A-Z]+-[0-9]+" "$file" 2>/dev/null | sed 's/trace://' | sort -u)
            if [ -n "$FILE_SPECS" ]; then
                SPEC_IDS="$SPEC_IDS $FILE_SPECS"
            fi
        fi
    done
    SPEC_IDS=$(echo "$SPEC_IDS" | tr ' ' '\n' | sort -u | tr '\n' ' ')

    if [ -n "$SPEC_IDS" ]; then
        # Check if commit message references these specs
        MISSING_REFS=""
        for spec in $SPEC_IDS; do
            if ! echo "$COMMIT_MSG" | grep -q "$spec"; then
                MISSING_REFS="$MISSING_REFS $spec"
            fi
        done

        if [ -n "$MISSING_REFS" ]; then
            echo -e "${YELLOW}⚠ Suggestion: Consider adding 'Trace:$MISSING_REFS' to your commit message${NC}"
            echo -e "${YELLOW}  These requirements are referenced in the staged files.${NC}"
            echo ""
        fi
    fi
fi

# Always allow the commit (non-blocking)
exit 0
"#
        .to_string()
    }

    /// Generate pre-commit git hook content
    pub(super) fn generate_pre_commit_hook(&self) -> String {
        r#"#!/bin/bash
# AIDA pre-commit hook - Validates trace comments
# Generated by AIDA scaffolding
# trace:FR-0226 | ai:claude:high

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

# Get staged files
STAGED_FILES=$(git diff --cached --name-only --diff-filter=ACM)

# Track warnings
WARNINGS=0

echo -e "${GREEN}AIDA: Checking trace comments...${NC}"

for file in $STAGED_FILES; do
    # Skip non-source files
    case "$file" in
        *.rs|*.py|*.js|*.ts|*.tsx|*.jsx|*.go|*.java|*.c|*.cpp|*.h|*.hpp)
            ;;
        *)
            continue
            ;;
    esac

    if [ -f "$file" ]; then
        # Extract spec IDs from trace comments
        TRACES=$(grep -oE "trace:[A-Z]+-[0-9]+" "$file" 2>/dev/null | sed 's/trace://' | sort -u)

        for spec_id in $TRACES; do
            # Check if the spec ID exists in the requirements database
            if command -v aida &> /dev/null; then
                if ! aida show "$spec_id" &> /dev/null; then
                    echo -e "${YELLOW}⚠ Warning: $file references unknown spec ID: $spec_id${NC}"
                    WARNINGS=$((WARNINGS + 1))
                fi
            fi
        done
    fi
done

if [ $WARNINGS -gt 0 ]; then
    echo -e "${YELLOW}Found $WARNINGS warning(s). Commit will proceed.${NC}"
fi

# Always allow the commit (non-blocking by default)
# To make blocking, change exit 0 to exit 1 when WARNINGS > 0
exit 0
"#
        .to_string()
    }

    /// Generate Claude Code validate-commit hook content
    pub(super) fn generate_validate_commit_hook(&self) -> String {
        r#"#!/bin/bash
# AIDA Claude Code Hook: Validate commits reference requirements
# PreToolUse hook for Bash commands
#
# This hook intercepts git commit commands and validates that:
# 1. Commit message includes a requirement ID (REQ-ID) for feat/fix commits
# 2. The referenced requirement exists in the database
#
# Exit codes:
#   0 - Allow the command
#   2 - Block the command (show stderr to Claude)

set -euo pipefail

# Read JSON input from stdin
input=$(cat)

# Extract the command being executed
command=$(echo "$input" | jq -r '.tool_input.command // ""')

# Only validate git commit commands
if ! echo "$command" | grep -qE '^git commit'; then
    exit 0  # Not a commit, allow
fi

# Skip if it's an amend or merge commit
if echo "$command" | grep -qE '(--amend|--no-edit|Merge)'; then
    exit 0
fi

# Extract commit message from -m flag
# Handle both single and double quotes
if echo "$command" | grep -qE '\-m "'; then
    msg=$(echo "$command" | sed -n 's/.*-m "\([^"]*\)".*/\1/p')
elif echo "$command" | grep -qE "\-m '"; then
    msg=$(echo "$command" | sed -n "s/.*-m '\\([^']*\\)'.*/\\1/p")
else
    # No inline message, might be using editor - allow
    exit 0
fi

# Check commit type - only require REQ-ID for feat/fix
commit_type=$(echo "$msg" | grep -oE '^(\[AI:[^\]]+\] )?(feat|fix|docs|style|refactor|perf|test|build|ci|chore|revert)' | tail -1 || true)

case "$commit_type" in
    *feat*|*fix*)
        # Require requirement ID for features and fixes
        if ! echo "$msg" | grep -qE '\([A-Z]+-[0-9]+\)'; then
            cat >&2 <<EOF
Commit blocked: Missing requirement ID

Your feat/fix commit must reference a requirement:
  Format: type(scope): description (REQ-ID)
  Example: feat(auth): add login validation (FR-0042)

Run 'aida list --status approved' to find requirement IDs.
To skip validation, use 'chore' or 'docs' type instead.
EOF
            exit 2  # Block the commit
        fi
        ;;
    *)
        # Other types (docs, chore, etc.) don't require REQ-ID
        exit 0
        ;;
esac

# Validate that the requirement exists
req_id=$(echo "$msg" | grep -oE '\([A-Z]+-[0-9]+\)' | head -1 | tr -d '()')

if [ -n "$req_id" ]; then
    if command -v aida &> /dev/null; then
        if ! aida show "$req_id" &> /dev/null 2>&1; then
            echo "Warning: Requirement $req_id not found in database" >&2
            # Non-blocking warning - exit 0 to allow, exit 2 to block
            exit 0
        fi
    fi
fi

exit 0  # Allow commit
"#
        .to_string()
    }

    /// Generate Claude Code track-commits hook content
    pub(super) fn generate_track_commits_hook(&self) -> String {
        r#"#!/bin/bash
# AIDA Claude Code Hook: Track commits and update requirement status
# PostToolUse hook for Bash commands
#
# This hook runs after successful git commit commands and:
# 1. Extracts requirement IDs from the commit message
# 2. Updates those requirements to "in-progress" status
# 3. Adds a comment noting the commit
#
# Exit codes:
#   0 - Success (always, this is informational only)

set -euo pipefail

# Read JSON input from stdin
input=$(cat)

# Extract command and response
command=$(echo "$input" | jq -r '.tool_input.command // ""')
tool_response=$(echo "$input" | jq -r '.tool_response // ""')

# Only process git commit commands
if ! echo "$command" | grep -qE '^git commit'; then
    exit 0
fi

# Check if commit was successful (look for success indicators in response)
if echo "$tool_response" | grep -qiE '(error|failed|abort)'; then
    exit 0  # Commit failed, don't update
fi

# Extract requirement IDs from commit message
req_ids=$(echo "$command" | grep -oE '\([A-Z]+-[0-9]+\)' | tr -d '()' | sort -u || true)

if [ -z "$req_ids" ]; then
    exit 0  # No requirements referenced
fi

# Check if aida CLI is available
if ! command -v aida &> /dev/null; then
    exit 0
fi

# Get the commit hash (if available)
commit_hash=$(git rev-parse --short HEAD 2>/dev/null || echo "unknown")

# Update each requirement
for req_id in $req_ids; do
    # Check current status
    current_status=$(aida show "$req_id" 2>/dev/null | grep -oE 'Status:\s*\w+' | awk '{print $2}' || true)

    case "$current_status" in
        Draft|Approved|Planned)
            # Transition to InProgress
            aida edit "$req_id" --status in-progress 2>/dev/null || true
            echo "Updated $req_id status to in-progress"
            ;;
        InProgress)
            # Already in progress, just add comment
            ;;
        Completed)
            # Already completed, skip
            continue
            ;;
    esac

    # Add commit reference as comment
    aida comment add "$req_id" "Commit $commit_hash references this requirement" 2>/dev/null || true
done

exit 0
"#
        .to_string()
    }
}
