name: Lighthouse audit

on:
  pull_request_target:

permissions:
  contents: read
  pull-requests: write

jobs:
  lighthouse:
    if: github.actor != 'dependabot[bot]'
    runs-on: ubuntu-latest

    steps:
      - name: Checkout PR code
        uses: actions/checkout@v6

      - name: Setup Node.js with npm cache
        uses: actions/setup-node@v6
        with:
          node-version: '22.x'
          cache: 'npm'

      - name: Install dependencies
        run: npm install lighthouse

      - name: Wait for Netlify preview to be live
        run: |
          PREVIEW_URL="https://deploy-preview-${{ github.event.pull_request.number }}--expressjscom-preview.netlify.app"
          echo "PREVIEW_URL=$PREVIEW_URL" >> "$GITHUB_ENV"
          MAX_RETRIES=10
          DELAY=10

          echo "Checking Netlify preview: $PREVIEW_URL"
          for i in $(seq 1 $MAX_RETRIES); do
            if curl -s -I "$PREVIEW_URL" | grep "HTTP/.* 200" > /dev/null; then
              echo "✅ Preview is live!"
              echo "skip_lighthouse=false" >> "$GITHUB_ENV"
              exit 0
            fi
            echo "⏳ Waiting for Netlify to deploy... ($i/$MAX_RETRIES)"
            sleep $DELAY
          done

          echo "❌ Preview not live after $((MAX_RETRIES*DELAY)) seconds."
          echo "skip_lighthouse=true" >> "$GITHUB_ENV"
          exit 0

      - name: Run Lighthouse audits
        if: env.skip_lighthouse == 'false'
        run: |
          URLS=(
            "$PREVIEW_URL"
            "$PREVIEW_URL/en/blog/posts.html"
            "$PREVIEW_URL/en/5x/api.html"
          )

          echo "## 🚦 Lighthouse Results (Mobile & Desktop)" > lighthouse-report.md
          echo "| URL | Device | Perf | A11y | Best Practices |" >> lighthouse-report.md
          echo "| --- | ------ | ---- | ---- | -------------- |" >> lighthouse-report.md

          for device in mobile desktop; do
            for url in "${URLS[@]}"; do  
              if [ "$device" = "desktop" ]; then
                lighthouse_args="--preset=desktop"
              else
                lighthouse_args="--form-factor=mobile"
              fi

              npx lighthouse "$url" \
                $lighthouse_args \
                --only-categories=performance,accessibility,best-practices \
                --output json \
                --output-path="lighthouse-report-${device}.json" \
                --chrome-flags="--headless"

              report="lighthouse-report-${device}.json"
              perf=$(jq '.categories | .performance.score * 100' $report)
              a11y=$(jq '.categories | .accessibility.score * 100' $report)
              bp=$(jq '.categories | .["best-practices"].score * 100' $report)

              stoplight() {
                if (( $(echo "$1 >= 90" | bc -l) )); then echo "🟢"; 
                elif (( $(echo "$1 >= 75" | bc -l) )); then echo "🟠"; 
                else echo "🔴"; fi
              }

              perf_stoplight=$(stoplight $perf)
              a11y_stoplight=$(stoplight $a11y)
              bp_stoplight=$(stoplight $bp)

              path=$(echo "$url" | sed "s|$PREVIEW_URL||")
              if [ -z "$path" ]; then path="/"; fi

              echo "| $path | $device | $perf_stoplight $(printf "%.0f" $perf) | $a11y_stoplight $(printf "%.0f" $a11y) | $bp_stoplight $(printf "%.0f" $bp) |" >> lighthouse-report.md
            done
          done

      - name: Log Lighthouse report
        if: env.skip_lighthouse == 'false'
        run: |
          cat lighthouse-report.md

      - name: Upload Lighthouse reports as artifacts
        if: env.skip_lighthouse == 'false'
        uses: actions/upload-artifact@v6
        with:
          name: lighthouse-reports
          path: |
            lighthouse-report.md

      - name: Comment on PR with Lighthouse results
        if: env.skip_lighthouse == 'false'
        uses: actions/github-script@v8
        with:
          github-token: ${{ secrets.GITHUB_TOKEN }}
          script: |
            const fs = require('fs');
            const report = fs.readFileSync('lighthouse-report.md', 'utf8');

            const { data: comments } = await github.rest.issues.listComments({
              issue_number: context.payload.pull_request.number,
              owner: context.repo.owner,
              repo: context.repo.repo,
            });

            const botComment = comments.find(comment =>
              comment.user.type === "Bot" &&
              comment.body.includes("🚦 Lighthouse Results")
            );

            if (botComment) {
              await github.rest.issues.updateComment({
                comment_id: botComment.id,
                owner: context.repo.owner,
                repo: context.repo.repo,
                body: report,
              });
              console.log("Updated existing Lighthouse comment.");
            } else {
              await github.rest.issues.createComment({
                issue_number: context.payload.pull_request.number,
                owner: context.repo.owner,
                repo: context.repo.repo,
                body: report,
              });
              console.log("Created new Lighthouse comment.");
            }
