#!/bin/bash
# visual-regression.sh - Script for visual regression testing
# Usage: ./bin/visual-regression.sh [capture|compare|report] [--threshold=5] [--page=login]

set -e

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

# Default settings
ACTION=""
DIFF_THRESHOLD=5
PAGE_FILTER=""
CURRENT_DATE=$(date +"%Y-%m-%d")
BASELINE_DIR="tests/e2e/visual-regression/baseline"
CURRENT_DIR="tests/e2e/visual-regression/current"
DIFF_DIR="tests/e2e/visual-regression/diff"
REPORT_DIR="tests/e2e/visual-regression/reports"

# Parse arguments
for arg in "$@"; do
  case $arg in
    capture|compare|report)
      ACTION="$arg"
      shift
      ;;
    --threshold=*)
      DIFF_THRESHOLD="${arg#*=}"
      shift
      ;;
    --page=*)
      PAGE_FILTER="${arg#*=}"
      shift
      ;;
  esac
done

# Check if action is provided
if [ -z "$ACTION" ]; then
  echo -e "${RED}Error: No action specified. Use: capture, compare, or report${NC}"
  exit 1
fi

echo -e "${GREEN}=== Visual Regression Testing - ${ACTION} ===${NC}"

# Check if we're in the right directory
if [ ! -d "tests/e2e" ]; then
  echo -e "${RED}Error: Please run this script from the wordpress-dev directory${NC}"
  exit 1
fi

# Check if ImageMagick is installed
if ! command -v compare &> /dev/null; then
  echo -e "${RED}Error: ImageMagick not found. Please install it to use this script.${NC}"
  echo "On macOS: brew install imagemagick"
  echo "On Ubuntu: sudo apt-get install imagemagick"
  exit 1
fi

# Create directory structure
mkdir -p "$BASELINE_DIR" "$CURRENT_DIR" "$DIFF_DIR" "$REPORT_DIR"

# Function to capture screenshots for visual regression
capture_screenshots() {
  echo -e "\n${YELLOW}Capturing screenshots for visual regression testing...${NC}"
  
  # Create a temporary Playwright test file
  TEMP_TEST="tests/e2e/visual-regression-temp.spec.ts"
  
  echo "Creating test file: $TEMP_TEST"
  cat > "$TEMP_TEST" << 'EOF'
import { test } from '@playwright/test';
import { LoginPage } from './pages/LoginPage';
import { DashboardPage } from './pages/DashboardPage';
import { TEST_USERS } from './data/test-users';

// Critical pages to capture
test('Capture critical pages for visual regression', async ({ page }) => {
  // Get target directory from environment variable
  const targetDir = process.env.SCREENSHOT_DIR || 'tests/e2e/visual-regression/current';
  console.log(`Capturing screenshots to: ${targetDir}`);
  
  // Login page
  const loginPage = new LoginPage(page);
  await loginPage.navigate();
  await page.waitForLoadState('networkidle');
  await page.screenshot({ path: `${targetDir}/login-page.png`, fullPage: true });
  console.log('Captured login page');
  
  // Login with test user
  await loginPage.login(TEST_USERS.trainer.username, TEST_USERS.trainer.password);
  
  // Dashboard page
  const dashboardPage = new DashboardPage(page);
  await dashboardPage.waitForDashboard();
  await page.waitForLoadState('networkidle');
  await page.screenshot({ path: `${targetDir}/dashboard-page.png`, fullPage: true });
  console.log('Captured dashboard page');
  
  // Events list
  if (await dashboardPage.isEventsTableVisible()) {
    await dashboardPage.filterEvents('all');
    await page.waitForLoadState('networkidle');
    await page.screenshot({ path: `${targetDir}/events-list.png`, fullPage: true });
    console.log('Captured events list');
  }
  
  // Create event page
  await dashboardPage.clickCreateEvent();
  await page.waitForLoadState('networkidle');
  await page.screenshot({ path: `${targetDir}/create-event-page.png`, fullPage: true });
  console.log('Captured create event page');
  
  // Certificate report page (if available)
  try {
    await page.goto('/certificates-report/');
    await page.waitForLoadState('networkidle');
    await page.screenshot({ path: `${targetDir}/certificate-report-page.png`, fullPage: true });
    console.log('Captured certificate report page');
  } catch (error) {
    console.log('Certificate report page not available');
  }
  
  console.log('Screenshot capture complete');
});
EOF
  
  # Run the test with the appropriate directory
  echo -e "${YELLOW}Running screenshot capture...${NC}"
  if [ -n "$PAGE_FILTER" ]; then
    echo "Capturing only ${PAGE_FILTER} page"
    SCREENSHOT_DIR="$CURRENT_DIR" npx playwright test "$TEMP_TEST" --grep="$PAGE_FILTER"
  else
    SCREENSHOT_DIR="$CURRENT_DIR" npx playwright test "$TEMP_TEST"
  fi
  
  # Clean up
  rm "$TEMP_TEST"
  
  echo -e "${GREEN}Screenshots captured successfully to ${CURRENT_DIR}${NC}"
}

# Function to establish baseline screenshots
establish_baseline() {
  echo -e "\n${YELLOW}Establishing baseline screenshots...${NC}"
  
  # Check if baseline directory is empty
  if [ -z "$(ls -A "$BASELINE_DIR" 2>/dev/null)" ]; then
    echo "Baseline directory is empty, capturing baseline screenshots..."
    
    # Set SCREENSHOT_DIR to baseline for the capture script
    SCREENSHOT_DIR="$BASELINE_DIR" capture_screenshots
  else
    echo "Baseline already exists. Use --force to overwrite."
    
    # Optionally copy current screenshots to baseline
    read -p "Copy current screenshots to baseline? (y/n) " -n 1 -r
    echo
    if [[ $REPLY =~ ^[Yy]$ ]]; then
      cp "$CURRENT_DIR"/*.png "$BASELINE_DIR"/ 2>/dev/null || true
      echo "Current screenshots copied to baseline."
    fi
  fi
}

# Function to compare screenshots
compare_screenshots() {
  echo -e "\n${YELLOW}Comparing screenshots against baseline...${NC}"
  
  # Check if baseline exists
  if [ -z "$(ls -A "$BASELINE_DIR" 2>/dev/null)" ]; then
    echo -e "${RED}Error: No baseline screenshots found. Run with 'capture' action first.${NC}"
    return 1
  fi
  
  # Check if current screenshots exist
  if [ -z "$(ls -A "$CURRENT_DIR" 2>/dev/null)" ]; then
    echo -e "${RED}Error: No current screenshots found. Run with 'capture' action first.${NC}"
    return 1
  fi
  
  # Create comparison report file
  REPORT_FILE="$REPORT_DIR/visual-diff-report-${CURRENT_DATE}.md"
  echo "# Visual Regression Test Report - ${CURRENT_DATE}" > "$REPORT_FILE"
  echo "" >> "$REPORT_FILE"
  echo "| Page | Diff % | Status | Diff Image |" >> "$REPORT_FILE"
  echo "|------|--------|--------|------------|" >> "$REPORT_FILE"
  
  FAILURE_COUNT=0
  SUCCESS_COUNT=0
  
  # Loop through each baseline image
  for baseline in "$BASELINE_DIR"/*.png; do
    filename=$(basename "$baseline")
    
    # If page filter is specified, only process that page
    if [ -n "$PAGE_FILTER" ] && [[ ! "$filename" == *"$PAGE_FILTER"* ]]; then
      continue
    fi
    
    current="$CURRENT_DIR/$filename"
    diff="$DIFF_DIR/$filename"
    
    # Skip if current image doesn't exist
    if [ ! -f "$current" ]; then
      echo -e "${YELLOW}Warning: Current screenshot ${filename} not found, skipping...${NC}"
      continue
    fi
    
    # Compare images
    echo -e "Comparing ${filename}..."
    compare_output=$(compare -metric AE "$baseline" "$current" "$diff" 2>&1 || true)
    
    # Get the pixel difference and calculate percentage
    pixel_diff=$(echo "$compare_output" | grep -o '[0-9]\+' || echo "0")
    total_pixels=$(identify -format "%w*%h" "$baseline" | bc)
    diff_percentage=$(echo "scale=2; $pixel_diff * 100 / $total_pixels" | bc)
    
    # Log the difference
    if (( $(echo "$diff_percentage > $DIFF_THRESHOLD" | bc -l) )); then
      echo -e "${RED}✗ ${filename} differs by ${diff_percentage}% (threshold: ${DIFF_THRESHOLD}%)${NC}"
      status="❌ Failed"
      FAILURE_COUNT=$((FAILURE_COUNT + 1))
    else
      echo -e "${GREEN}✓ ${filename} passed (${diff_percentage}% difference)${NC}"
      status="✅ Passed"
      SUCCESS_COUNT=$((SUCCESS_COUNT + 1))
    fi
    
    # Add to report
    echo "| ${filename} | ${diff_percentage}% | ${status} | ![Diff](../diff/${filename}) |" >> "$REPORT_FILE"
  done
  
  # Add summary to report
  echo "" >> "$REPORT_FILE"
  echo "## Summary" >> "$REPORT_FILE"
  echo "" >> "$REPORT_FILE"
  echo "- **Date:** ${CURRENT_DATE}" >> "$REPORT_FILE"
  echo "- **Total Comparisons:** $((SUCCESS_COUNT + FAILURE_COUNT))" >> "$REPORT_FILE"
  echo "- **Passed:** ${SUCCESS_COUNT}" >> "$REPORT_FILE"
  echo "- **Failed:** ${FAILURE_COUNT}" >> "$REPORT_FILE"
  echo "- **Threshold:** ${DIFF_THRESHOLD}%" >> "$REPORT_FILE"
  
  # Output summary
  echo -e "\n${GREEN}Comparison complete:${NC}"
  echo "Total: $((SUCCESS_COUNT + FAILURE_COUNT))"
  echo "Passed: ${SUCCESS_COUNT}"
  echo "Failed: ${FAILURE_COUNT}"
  echo "Report: ${REPORT_FILE}"
  
  # Return success/failure
  if [ $FAILURE_COUNT -eq 0 ]; then
    return 0
  else
    return 1
  fi
}

# Function to generate a visual regression report
generate_report() {
  echo -e "\n${YELLOW}Generating visual regression report...${NC}"
  
  # Check if we have diff images
  if [ -z "$(ls -A "$DIFF_DIR" 2>/dev/null)" ]; then
    echo -e "${RED}Error: No diff images found. Run with 'compare' action first.${NC}"
    return 1
  fi
  
  # Create an HTML report
  HTML_REPORT="$REPORT_DIR/visual-diff-report-${CURRENT_DATE}.html"
  
  cat > "$HTML_REPORT" << EOF
<!DOCTYPE html>
<html>
<head>
  <title>Visual Regression Test Report - ${CURRENT_DATE}</title>
  <style>
    body { font-family: Arial, sans-serif; margin: 20px; }
    h1 { color: #333; }
    .summary { margin: 20px 0; padding: 10px; background: #f5f5f5; border-radius: 5px; }
    .comparison { margin-bottom: 30px; border: 1px solid #ddd; padding: 15px; border-radius: 5px; }
    .comparison h3 { margin-top: 0; }
    .comparison.fail { border-left: 5px solid #ff0000; }
    .comparison.pass { border-left: 5px solid #00cc00; }
    .images { display: flex; flex-wrap: wrap; }
    .image-container { margin: 10px; text-align: center; }
    img { max-width: 100%; border: 1px solid #ddd; }
    .status { font-weight: bold; }
    .pass-status { color: #00cc00; }
    .fail-status { color: #ff0000; }
  </style>
</head>
<body>
  <h1>Visual Regression Test Report - ${CURRENT_DATE}</h1>
  
  <div class="summary">
    <h2>Summary</h2>
    <p><strong>Date:</strong> ${CURRENT_DATE}</p>
    <p><strong>Threshold:</strong> ${DIFF_THRESHOLD}%</p>
EOF
  
  # Add comparison sections
  for diff in "$DIFF_DIR"/*.png; do
    if [ -f "$diff" ]; then
      filename=$(basename "$diff")
      baseline="$BASELINE_DIR/$filename"
      current="$CURRENT_DIR/$filename"
      
      # Skip if baseline or current image doesn't exist
      if [ ! -f "$baseline" ] || [ ! -f "$current" ]; then
        continue
      }
      
      # Get the pixel difference and calculate percentage
      compare_output=$(compare -metric AE "$baseline" "$current" "$diff" 2>&1 || true)
      pixel_diff=$(echo "$compare_output" | grep -o '[0-9]\+' || echo "0")
      total_pixels=$(identify -format "%w*%h" "$baseline" | bc)
      diff_percentage=$(echo "scale=2; $pixel_diff * 100 / $total_pixels" | bc)
      
      # Determine status
      if (( $(echo "$diff_percentage > $DIFF_THRESHOLD" | bc -l) )); then
        status_class="fail"
        status_text="Failed"
        status_style="fail-status"
      else
        status_class="pass"
        status_text="Passed"
        status_style="pass-status"
      fi
      
      # Add to HTML report
      cat >> "$HTML_REPORT" << EOF
  <div class="comparison ${status_class}">
    <h3>${filename}</h3>
    <p>Difference: ${diff_percentage}% - <span class="status ${status_style}">${status_text}</span></p>
    <div class="images">
      <div class="image-container">
        <p>Baseline</p>
        <img src="../baseline/${filename}" alt="Baseline">
      </div>
      <div class="image-container">
        <p>Current</p>
        <img src="../current/${filename}" alt="Current">
      </div>
      <div class="image-container">
        <p>Diff</p>
        <img src="../diff/${filename}" alt="Diff">
      </div>
    </div>
  </div>
EOF
    fi
  done
  
  # Close HTML
  cat >> "$HTML_REPORT" << EOF
</body>
</html>
EOF
  
  echo -e "${GREEN}HTML report generated: ${HTML_REPORT}${NC}"
  return 0
}

# Execute action
case $ACTION in
  "capture")
    capture_screenshots
    ;;
  "baseline")
    establish_baseline
    ;;
  "compare")
    capture_screenshots
    compare_screenshots
    ;;
  "report")
    generate_report
    ;;
  *)
    echo -e "${RED}Invalid action: ${ACTION}${NC}"
    exit 1
    ;;
esac

echo -e "\n${GREEN}=== Visual Regression Testing Complete ===${NC}"
exit 0