#!/bin/bash

###############################################################################
# Frontend Performance Audit Script
#
# Comprehensive performance testing for Global Gala Next.js/React apps
# Tests: Lighthouse scores, bundle size, Core Web Vitals, asset optimization
#
# Usage: ./scripts/frontend-performance-audit.sh
###############################################################################

set -eo pipefail

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

# Counters
PASS=0
FAIL=0
WARN=0

# Configuration
FRONTEND_PATH="/Users/charlie/code/showprima-frontend"
TICKETING_APP="${FRONTEND_PATH}/apps/ticketing"
ADMIN_APP="${FRONTEND_PATH}/apps/admin"
TICKETING_URL="http://localhost:3002"
ADMIN_URL="http://localhost:3001"

# Performance budgets (in KB)
MAX_INITIAL_JS=200
MAX_TOTAL_JS=500
MAX_CSS=50
MAX_TOTAL_SIZE=1000

# Logging
info() {
    echo -e "${BLUE}[INFO]${NC} $1"
}

pass() {
    echo -e "${GREEN}[PASS]${NC} $1"
    ((PASS++))
}

fail() {
    echo -e "${RED}[FAIL]${NC} $1"
    ((FAIL++))
}

warn() {
    echo -e "${YELLOW}[WARN]${NC} $1"
    ((WARN++))
}

header() {
    echo ""
    echo -e "${BLUE}===================================================${NC}"
    echo -e "${BLUE}$1${NC}"
    echo -e "${BLUE}===================================================${NC}"
    echo ""
}

# Convert bytes to KB
bytes_to_kb() {
    echo "scale=2; $1 / 1024" | bc
}

###############################################################################
# Prerequisites
###############################################################################

header "Performance Audit - Prerequisites"

# Check if apps are built
info "Checking if frontend apps are built..."

if [ ! -d "$TICKETING_APP/.next" ]; then
    warn "Ticketing app not built. Run: cd $FRONTEND_PATH && npm run build"
fi

if [ ! -d "$ADMIN_APP/.next" ]; then
    warn "Admin app not built. Run: cd $FRONTEND_PATH && npm run build"
fi

# Check for required tools
if ! command -v node &> /dev/null; then
    fail "Node.js not installed"
    exit 1
fi

# Check for lighthouse
if ! command -v lighthouse &> /dev/null; then
    warn "Lighthouse not installed. Installing..."
    npm install -g @lhci/cli lighthouse || {
        fail "Failed to install Lighthouse"
        exit 1
    }
fi

###############################################################################
# 1. Bundle Size Analysis
###############################################################################

header "1. Bundle Size Analysis"

cd "$FRONTEND_PATH"

if [ -d "$TICKETING_APP/.next" ]; then
    info "Analyzing ticketing app bundle size..."

    # Find main JavaScript bundle
    MAIN_JS=$(find "$TICKETING_APP/.next/static/chunks" -name "main-*.js" -type f 2>/dev/null | head -n 1)

    if [ -n "$MAIN_JS" ]; then
        MAIN_SIZE=$(stat -f%z "$MAIN_JS" 2>/dev/null || stat -c%s "$MAIN_JS" 2>/dev/null)
        MAIN_SIZE_KB=$(bytes_to_kb "$MAIN_SIZE")

        echo "Main bundle size: ${MAIN_SIZE_KB}KB"

        if (( $(echo "$MAIN_SIZE_KB < $MAX_INITIAL_JS" | bc -l) )); then
            pass "Main bundle within budget (${MAIN_SIZE_KB}KB < ${MAX_INITIAL_JS}KB)"
        elif (( $(echo "$MAIN_SIZE_KB < $MAX_INITIAL_JS * 1.1" | bc -l) )); then
            warn "Main bundle near budget limit (${MAIN_SIZE_KB}KB, budget: ${MAX_INITIAL_JS}KB)"
        else
            fail "Main bundle exceeds budget (${MAIN_SIZE_KB}KB > ${MAX_INITIAL_JS}KB)"
        fi
    fi

    # Calculate total JavaScript size
    TOTAL_JS=$(find "$TICKETING_APP/.next/static" -name "*.js" -type f -exec stat -f%z {} \; 2>/dev/null | awk '{sum+=$1} END {print sum}')
    if [ -z "$TOTAL_JS" ]; then
        TOTAL_JS=$(find "$TICKETING_APP/.next/static" -name "*.js" -type f -exec stat -c%s {} \; 2>/dev/null | awk '{sum+=$1} END {print sum}')
    fi

    if [ -n "$TOTAL_JS" ]; then
        TOTAL_JS_KB=$(bytes_to_kb "$TOTAL_JS")
        echo "Total JavaScript: ${TOTAL_JS_KB}KB"

        if (( $(echo "$TOTAL_JS_KB < $MAX_TOTAL_JS" | bc -l) )); then
            pass "Total JavaScript within budget (${TOTAL_JS_KB}KB < ${MAX_TOTAL_JS}KB)"
        else
            fail "Total JavaScript exceeds budget (${TOTAL_JS_KB}KB > ${MAX_TOTAL_JS}KB)"
        fi
    fi

    # Calculate CSS size
    TOTAL_CSS=$(find "$TICKETING_APP/.next/static" -name "*.css" -type f -exec stat -f%z {} \; 2>/dev/null | awk '{sum+=$1} END {print sum}')
    if [ -z "$TOTAL_CSS" ]; then
        TOTAL_CSS=$(find "$TICKETING_APP/.next/static" -name "*.css" -type f -exec stat -c%s {} \; 2>/dev/null | awk '{sum+=$1} END {print sum}')
    fi

    if [ -n "$TOTAL_CSS" ] && [ "$TOTAL_CSS" -gt 0 ]; then
        TOTAL_CSS_KB=$(bytes_to_kb "$TOTAL_CSS")
        echo "Total CSS: ${TOTAL_CSS_KB}KB"

        if (( $(echo "$TOTAL_CSS_KB < $MAX_CSS" | bc -l) )); then
            pass "CSS within budget (${TOTAL_CSS_KB}KB < ${MAX_CSS}KB)"
        else
            warn "CSS exceeds budget (${TOTAL_CSS_KB}KB > ${MAX_CSS}KB)"
        fi
    fi

    # Check for code splitting
    CHUNK_COUNT=$(find "$TICKETING_APP/.next/static/chunks" -name "*.js" -type f 2>/dev/null | wc -l)
    echo "Number of chunks: $CHUNK_COUNT"

    if [ "$CHUNK_COUNT" -gt 10 ]; then
        pass "Good code splitting ($CHUNK_COUNT chunks)"
    elif [ "$CHUNK_COUNT" -gt 5 ]; then
        info "Moderate code splitting ($CHUNK_COUNT chunks)"
    else
        warn "Limited code splitting ($CHUNK_COUNT chunks) - consider dynamic imports"
    fi
fi

###############################################################################
# 2. Source Map Detection (Security)
###############################################################################

header "2. Source Map Detection"

if [ -d "$TICKETING_APP/.next" ]; then
    SOURCE_MAPS=$(find "$TICKETING_APP/.next" -name "*.map" 2>/dev/null | wc -l)

    if [ "$SOURCE_MAPS" -gt 0 ]; then
        fail "Found $SOURCE_MAPS source map files in production build!"
        echo "     Source maps expose original source code. Disable with:"
        echo "     // next.config.js"
        echo "     productionBrowserSourceMaps: false"
    else
        pass "No source maps in production build"
    fi
fi

###############################################################################
# 3. Image Optimization
###############################################################################

header "3. Image Optimization"

if [ -d "$TICKETING_APP/public" ]; then
    info "Analyzing image assets..."

    # Find large images
    LARGE_IMAGES=$(find "$TICKETING_APP/public" -type f \( -name "*.jpg" -o -name "*.png" -o -name "*.jpeg" \) -size +500k 2>/dev/null)

    if [ -n "$LARGE_IMAGES" ]; then
        IMAGE_COUNT=$(echo "$LARGE_IMAGES" | wc -l)
        warn "Found $IMAGE_COUNT images larger than 500KB:"
        echo "$LARGE_IMAGES" | while read -r img; do
            SIZE=$(stat -f%z "$img" 2>/dev/null || stat -c%s "$img" 2>/dev/null)
            SIZE_KB=$(bytes_to_kb "$SIZE")
            echo "      - $(basename "$img"): ${SIZE_KB}KB"
        done
        echo "     Consider using Next.js Image component for optimization"
    else
        pass "No large images detected"
    fi

    # Check for WebP usage
    WEBP_COUNT=$(find "$TICKETING_APP/public" -name "*.webp" 2>/dev/null | wc -l)
    PNG_JPG_COUNT=$(find "$TICKETING_APP/public" \( -name "*.jpg" -o -name "*.png" -o -name "*.jpeg" \) 2>/dev/null | wc -l)

    if [ "$PNG_JPG_COUNT" -gt 0 ]; then
        if [ "$WEBP_COUNT" -gt 0 ]; then
            info "Using modern image formats (WebP): $WEBP_COUNT files"
            pass "WebP images present"
        else
            warn "No WebP images found - consider converting to WebP for better compression"
        fi
    fi
fi

###############################################################################
# 4. Font Optimization
###############################################################################

header "4. Font Optimization"

if [ -d "$TICKETING_APP/public" ]; then
    info "Checking font files..."

    FONT_SIZE=$(find "$TICKETING_APP/public" -type f \( -name "*.woff" -o -name "*.woff2" -o -name "*.ttf" \) -exec stat -f%z {} \; 2>/dev/null | awk '{sum+=$1} END {print sum}')
    if [ -z "$FONT_SIZE" ]; then
        FONT_SIZE=$(find "$TICKETING_APP/public" -type f \( -name "*.woff" -o -name "*.woff2" -o -name "*.ttf" \) -exec stat -c%s {} \; 2>/dev/null | awk '{sum+=$1} END {print sum}')
    fi

    if [ -n "$FONT_SIZE" ] && [ "$FONT_SIZE" -gt 0 ]; then
        FONT_SIZE_KB=$(bytes_to_kb "$FONT_SIZE")
        echo "Total font size: ${FONT_SIZE_KB}KB"

        if (( $(echo "$FONT_SIZE_KB < 100" | bc -l) )); then
            pass "Font files within budget (${FONT_SIZE_KB}KB < 100KB)"
        else
            warn "Font files exceed budget (${FONT_SIZE_KB}KB > 100KB)"
        fi
    else
        info "No custom font files detected (likely using system fonts or CDN)"
    fi
fi

###############################################################################
# 5. Dependency Analysis
###############################################################################

header "5. Dependency Analysis"

cd "$FRONTEND_PATH"

info "Analyzing package dependencies..."

if [ -f "package.json" ]; then
    DEPS_COUNT=$(cat package.json | grep -c '".*":' || echo "0")
    echo "Total dependencies declared: $DEPS_COUNT"

    # Check for duplicate packages
    if [ -f "package-lock.json" ]; then
        info "Checking for duplicate dependencies..."

        # This is a simplified check - full analysis requires depcheck
        DUPLICATES=$(cat package-lock.json | grep '"version"' | sort | uniq -d | wc -l)

        if [ "$DUPLICATES" -gt 10 ]; then
            warn "Potential duplicate dependencies detected ($DUPLICATES)"
            echo "     Run: npx depcheck"
        else
            pass "Minimal duplicate dependencies"
        fi
    fi

    # Check for large dependencies
    info "Consider running: npx bundle-buddy to find large dependencies"
fi

###############################################################################
# 6. Lighthouse Performance Test
###############################################################################

header "6. Lighthouse Performance Audit"

# Check if apps are running
APPS_RUNNING=false

if curl -s -o /dev/null -w "%{http_code}" "$TICKETING_URL" | grep -q "200"; then
    APPS_RUNNING=true
    info "Ticketing app is running at $TICKETING_URL"
else
    warn "Ticketing app not running. Start with: npm run dev"
fi

if [ "$APPS_RUNNING" = true ]; then
    info "Running Lighthouse audit on ticketing app..."

    # Create temporary directory for reports
    REPORT_DIR="./lighthouse-reports"
    mkdir -p "$REPORT_DIR"

    # Run Lighthouse
    lighthouse "$TICKETING_URL/booking/1" \
        --output=json \
        --output=html \
        --output-path="$REPORT_DIR/ticketing-report" \
        --only-categories=performance,accessibility,best-practices \
        --chrome-flags="--headless --no-sandbox" \
        --quiet 2>/dev/null || {
            warn "Lighthouse audit failed (app may not be ready)"
        }

    if [ -f "$REPORT_DIR/ticketing-report.report.json" ]; then
        # Parse Lighthouse scores
        PERF_SCORE=$(cat "$REPORT_DIR/ticketing-report.report.json" | grep -o '"performance":[0-9.]*' | head -n1 | cut -d: -f2)
        A11Y_SCORE=$(cat "$REPORT_DIR/ticketing-report.report.json" | grep -o '"accessibility":[0-9.]*' | head -n1 | cut -d: -f2)
        BP_SCORE=$(cat "$REPORT_DIR/ticketing-report.report.json" | grep -o '"best-practices":[0-9.]*' | head -n1 | cut -d: -f2)

        # Convert to percentage
        PERF_PERCENT=$(echo "scale=0; $PERF_SCORE * 100" | bc)
        A11Y_PERCENT=$(echo "scale=0; $A11Y_SCORE * 100" | bc)
        BP_PERCENT=$(echo "scale=0; $BP_SCORE * 100" | bc)

        echo ""
        echo "Lighthouse Scores:"
        echo "=================="
        echo "Performance:      $PERF_PERCENT/100"
        echo "Accessibility:    $A11Y_PERCENT/100"
        echo "Best Practices:   $BP_PERCENT/100"
        echo ""

        # Performance grading
        if [ "$PERF_PERCENT" -ge 90 ]; then
            pass "Excellent performance score ($PERF_PERCENT/100)"
        elif [ "$PERF_PERCENT" -ge 80 ]; then
            pass "Good performance score ($PERF_PERCENT/100)"
        elif [ "$PERF_PERCENT" -ge 70 ]; then
            warn "Moderate performance score ($PERF_PERCENT/100)"
        else
            fail "Poor performance score ($PERF_PERCENT/100)"
        fi

        # Accessibility grading
        if [ "$A11Y_PERCENT" -ge 90 ]; then
            pass "Excellent accessibility score ($A11Y_PERCENT/100)"
        elif [ "$A11Y_PERCENT" -ge 80 ]; then
            warn "Good accessibility score ($A11Y_PERCENT/100)"
        else
            fail "Poor accessibility score ($A11Y_PERCENT/100)"
        fi

        info "Full report: $REPORT_DIR/ticketing-report.report.html"
    fi
fi

###############################################################################
# 7. Core Web Vitals Check
###############################################################################

header "7. Core Web Vitals"

if [ -f "$REPORT_DIR/ticketing-report.report.json" ]; then
    info "Analyzing Core Web Vitals..."

    # Extract metrics (simplified - full parsing needs jq)
    echo "Metrics from Lighthouse:"
    echo "========================"
    echo ""
    info "For detailed Core Web Vitals, use Chrome DevTools or web.dev/measure"
    echo ""
    echo "Target metrics (WCAG Level AA):"
    echo "  - LCP (Largest Contentful Paint): < 2.5s"
    echo "  - FID (First Input Delay): < 100ms"
    echo "  - CLS (Cumulative Layout Shift): < 0.1"
    echo "  - TTFB (Time to First Byte): < 800ms"
fi

###############################################################################
# Summary
###############################################################################

header "Performance Audit Summary"

echo ""
echo -e "${GREEN}Passed:${NC}    $PASS tests"
echo -e "${YELLOW}Warnings:${NC}  $WARN tests"
echo -e "${RED}Failed:${NC}    $FAIL tests"
echo ""

# Calculate score
TOTAL=$((PASS + WARN + FAIL))
if [ $TOTAL -eq 0 ]; then
    SCORE=0
else
    SCORE=$(( (PASS * 100) / TOTAL ))
fi

echo "Performance Score: $SCORE/100"

# Grade
if [ $SCORE -ge 90 ]; then
    echo -e "${GREEN}Grade: A (Excellent)${NC}"
    EXIT_CODE=0
elif [ $SCORE -ge 80 ]; then
    echo -e "${GREEN}Grade: B (Good)${NC}"
    EXIT_CODE=0
elif [ $SCORE -ge 70 ]; then
    echo -e "${YELLOW}Grade: C (Acceptable)${NC}"
    EXIT_CODE=0
elif [ $SCORE -ge 60 ]; then
    echo -e "${YELLOW}Grade: D (Needs Improvement)${NC}"
    EXIT_CODE=1
else
    echo -e "${RED}Grade: F (Failing)${NC}"
    EXIT_CODE=1
fi

echo ""
echo "Performance Optimization Recommendations:"
echo "=========================================="

if [ $FAIL -gt 0 ]; then
    echo "⚠️  Address failed performance checks before deployment"
fi

echo "✅ Implement code splitting for large bundles"
echo "✅ Use Next.js Image component for automatic optimization"
echo "✅ Enable Brotli/Gzip compression on server"
echo "✅ Implement lazy loading for below-the-fold content"
echo "✅ Use dynamic imports for heavy components"
echo "✅ Optimize font loading with font-display: swap"
echo "✅ Remove unused dependencies with: npx depcheck"
echo "✅ Analyze bundle with: npm run build && npm run analyze"

echo ""
echo "Additional Performance Tools:"
echo "============================="
echo "• Chrome DevTools Performance Panel"
echo "• WebPageTest: https://www.webpagetest.org/"
echo "• Bundle Analyzer: npx @next/bundle-analyzer"
echo "• Lighthouse CI in GitHub Actions"

echo ""
echo "Report generated: $(date)"
echo ""

exit $EXIT_CODE
