#!/bin/bash

# Prowler UI - Pre-Commit Hook
# Optionally validates ONLY staged files against AGENTS.md standards using Claude Code
# Controlled by CODE_REVIEW_ENABLED in .env

set -e

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

echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "🚀 Prowler UI - Pre-Commit Hook"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo ""

# Load .env file (look in git root directory)
GIT_ROOT=$(git rev-parse --show-toplevel)
if [ -f "$GIT_ROOT/ui/.env" ]; then
  CODE_REVIEW_ENABLED=$(grep "^CODE_REVIEW_ENABLED" "$GIT_ROOT/ui/.env" | cut -d'=' -f2 | tr -d ' ')
elif [ -f "$GIT_ROOT/.env" ]; then
  CODE_REVIEW_ENABLED=$(grep "^CODE_REVIEW_ENABLED" "$GIT_ROOT/.env" | cut -d'=' -f2 | tr -d ' ')
elif [ -f ".env" ]; then
  CODE_REVIEW_ENABLED=$(grep "^CODE_REVIEW_ENABLED" .env | cut -d'=' -f2 | tr -d ' ')
else
  CODE_REVIEW_ENABLED="false"
fi

# Normalize the value to lowercase
CODE_REVIEW_ENABLED=$(echo "$CODE_REVIEW_ENABLED" | tr '[:upper:]' '[:lower:]')

echo -e "${BLUE}ℹ️  Code Review Status: ${CODE_REVIEW_ENABLED}${NC}"
echo ""

# Get staged files in the UI folder only (what will be committed)
STAGED_FILES=$(git diff --cached --name-only --diff-filter=ACM -- 'ui/**' | grep -E '\.(tsx?|jsx?)$' || true)

if [ "$CODE_REVIEW_ENABLED" = "true" ]; then
  if [ -z "$STAGED_FILES" ]; then
    echo -e "${YELLOW}⚠️  No TypeScript/JavaScript files staged to validate${NC}"
    echo ""
  else
    echo -e "${YELLOW}🔍 Running Claude Code standards validation...${NC}"
    echo ""
    echo -e "${BLUE}📋 Files to validate:${NC}"
    echo "$STAGED_FILES" | while IFS= read -r file; do echo "  - $file"; done
    echo ""

    echo -e "${BLUE}📤 Sending to Claude Code for validation...${NC}"
    echo ""

    # Build prompt with full file contents
    VALIDATION_PROMPT=$(
      cat <<'PROMPT_EOF'
You are a code reviewer for the Prowler UI project. Analyze the full file contents of changed files below and validate they comply with AGENTS.md standards.

**RULES TO CHECK:**
1. React Imports: NO `import * as React` or `import React, {` → Use `import { useState }`
2. TypeScript: NO union types like `type X = "a" | "b"` → Use const-based: `const X = {...} as const`
3. Tailwind: NO `var()` or hex colors in className → Use Tailwind utilities and semantic color classes. Exception: `var()` is allowed when passing colors to chart/graph components that require CSS color strings (not Tailwind classes) for their APIs.
4. cn(): Use for merging multiple classes or for conditionals (handles Tailwind conflicts with twMerge) → `cn(BUTTON_STYLES.base, BUTTON_STYLES.active, isLoading && "opacity-50")`
5. React 19: NO `useMemo`/`useCallback` without reason
6. Zod v4: Use `.min(1)` not `.nonempty()`, `z.email()` not `z.string().email()`. All inputs must be validated with Zod.
7. File Org: 1 feature = local, 2+ features = shared
8. Directives: Server Actions need "use server", clients need "use client"
9. Implement DRY, KISS principles. (example: reusable components, avoid repetition)
10. Layout must work for all the responsive breakpoints (mobile, tablet, desktop)
11. ANY types cannot be used - CRITICAL: Check for `: any` in all visible lines
12. Use the components inside components/shadcn if possible
13. Check Accessibility best practices (like alt tags in images, semantic HTML, Aria labels, etc.)

=== FILES TO REVIEW ===
PROMPT_EOF
    )

    # Add full file contents for each staged file
    for file in $STAGED_FILES; do
      VALIDATION_PROMPT="$VALIDATION_PROMPT

=== FILE: $file ===
$(cat "$file" 2>/dev/null || echo "Error reading file")"
    done

    VALIDATION_PROMPT="$VALIDATION_PROMPT

=== END FILES ===

**IMPORTANT: Your response MUST start with exactly one of these lines:**
STATUS: PASSED
STATUS: FAILED

**If FAILED:** List each violation with File, Line Number, Rule Number, and Issue.
**If PASSED:** Confirm all files comply with AGENTS.md standards.

**Start your response now with STATUS:**"

    # Send to Claude Code
    if VALIDATION_OUTPUT=$(echo "$VALIDATION_PROMPT" | claude 2>&1); then
      echo "$VALIDATION_OUTPUT"
      echo ""

      # Check result - STRICT MODE: fail if status unclear
      if echo "$VALIDATION_OUTPUT" | grep -q "^STATUS: PASSED"; then
        echo ""
        echo -e "${GREEN}✅ VALIDATION PASSED${NC}"
        echo ""
      elif echo "$VALIDATION_OUTPUT" | grep -q "^STATUS: FAILED"; then
        echo ""
        echo -e "${RED}❌ VALIDATION FAILED${NC}"
        echo -e "${RED}Fix violations before committing${NC}"
        echo ""
        exit 1
      else
        echo ""
        echo -e "${RED}❌ VALIDATION ERROR${NC}"
        echo -e "${RED}Could not determine validation status from Claude Code response${NC}"
        echo -e "${YELLOW}Response must start with 'STATUS: PASSED' or 'STATUS: FAILED'${NC}"
        echo ""
        echo -e "${YELLOW}To bypass validation temporarily, set CODE_REVIEW_ENABLED=false in .env${NC}"
        echo ""
        exit 1
      fi
    else
      echo -e "${YELLOW}⚠️  Claude Code not available${NC}"
    fi
    echo ""
  fi
else
  echo -e "${YELLOW}⏭️  Code review disabled (CODE_REVIEW_ENABLED=false)${NC}"
  echo ""
fi

# Check if there are any UI files to validate
if [ -z "$STAGED_FILES" ] && [ "$CODE_REVIEW_ENABLED" = "true" ]; then
  echo -e "${YELLOW}⏭️  No UI files to validate, skipping healthcheck${NC}"
  echo ""
  exit 0
fi

# Run healthcheck (typecheck and lint check) only if there are UI changes
echo -e "${BLUE}🏥 Running healthcheck...${NC}"
echo ""

cd ui || cd .
if pnpm run healthcheck; then
  echo ""
  echo -e "${GREEN}✅ Healthcheck passed${NC}"
  echo ""
else
  echo ""
  echo -e "${RED}❌ Healthcheck failed${NC}"
  echo -e "${RED}Fix type errors and linting issues before committing${NC}"
  echo ""
  exit 1
fi

# Run unit tests (targeted based on staged files)
echo -e "${BLUE}🧪 Running unit tests...${NC}"
echo ""

# Get staged source files (exclude test files)
# Note: we already cd'd into ui/, so pathspecs are relative (no ui/ prefix)
STAGED_SOURCE_FILES=$(git diff --cached --name-only --diff-filter=ACM -- '*.ts' '*.tsx' | grep -v '\.test\.\|\.spec\.\|vitest\.config\|vitest\.setup' || true)

# Check if critical paths changed (lib/, types/, config/)
CRITICAL_PATHS_CHANGED=$(git diff --cached --name-only -- 'lib/**' 'types/**' 'config/**' 'middleware.ts' 'vitest.config.ts' 'vitest.setup.ts' || true)

if [ -n "$CRITICAL_PATHS_CHANGED" ]; then
  echo -e "${YELLOW}Critical paths changed - running ALL unit tests${NC}"
  if pnpm run test:run; then
    echo ""
    echo -e "${GREEN}✅ Unit tests passed${NC}"
    echo ""
  else
    echo ""
    echo -e "${RED}❌ Unit tests failed${NC}"
    echo -e "${RED}Fix failing tests before committing${NC}"
    echo ""
    exit 1
  fi
elif [ -n "$STAGED_SOURCE_FILES" ]; then
  echo -e "${YELLOW}Running tests related to changed files:${NC}"
  echo "$STAGED_SOURCE_FILES" | while IFS= read -r file; do [ -n "$file" ] && echo "  - $file"; done
  echo ""
  # shellcheck disable=SC2086 # Word splitting is intentional - vitest needs each file as separate arg
  if pnpm exec vitest related $STAGED_SOURCE_FILES --run; then
    echo ""
    echo -e "${GREEN}✅ Unit tests passed${NC}"
    echo ""
  else
    echo ""
    echo -e "${RED}❌ Unit tests failed${NC}"
    echo -e "${RED}Fix failing tests before committing${NC}"
    echo ""
    exit 1
  fi
else
  echo -e "${YELLOW}No source files changed - running ALL unit tests${NC}"
  if pnpm run test:run; then
    echo ""
    echo -e "${GREEN}✅ Unit tests passed${NC}"
    echo ""
  else
    echo ""
    echo -e "${RED}❌ Unit tests failed${NC}"
    echo -e "${RED}Fix failing tests before committing${NC}"
    echo ""
    exit 1
  fi
fi

# Run build
echo -e "${BLUE}🔨 Running build...${NC}"
echo ""

if pnpm run build; then
  echo ""
  echo -e "${GREEN}✅ Build passed${NC}"
  echo ""
else
  echo ""
  echo -e "${RED}❌ Build failed${NC}"
  echo -e "${RED}Fix build errors before committing${NC}"
  echo ""
  exit 1
fi
