name: CI

on:
  push:
    branches: [main, master]
  pull_request:
    branches: [main, master]

jobs:
  typecheck:
    name: TypeScript
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'npm'

      - name: Install dependencies
        run: npm ci

      - name: Type check
        run: npx tsc --noEmit

  lint:
    name: ESLint
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'npm'

      - name: Install dependencies
        run: npm ci

      - name: Lint
        run: npm run lint

  test:
    name: Tests
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'npm'

      - name: Install dependencies
        run: npm ci

      - name: Run unit tests with coverage
        run: npm run test:coverage

      - name: Run component render tests
        run: npm run test:render

      - name: Upload coverage report
        uses: actions/upload-artifact@v4
        if: always()
        with:
          name: coverage-report
          path: coverage/
          retention-days: 7

      - name: Coverage summary
        if: always()
        run: |
          echo "## Test Coverage Summary" >> $GITHUB_STEP_SUMMARY
          echo "" >> $GITHUB_STEP_SUMMARY
          if [ -f coverage/coverage-summary.json ]; then
            echo '```' >> $GITHUB_STEP_SUMMARY
            node -e "
              const c = require('./coverage/coverage-summary.json').total;
              const fmt = (v) => v.pct + '%';
              console.log('Statements: ' + fmt(c.statements));
              console.log('Branches:   ' + fmt(c.branches));
              console.log('Functions:  ' + fmt(c.functions));
              console.log('Lines:      ' + fmt(c.lines));
            " >> $GITHUB_STEP_SUMMARY
            echo '```' >> $GITHUB_STEP_SUMMARY
          elif [ -f coverage/coverage-final.json ]; then
            echo "Coverage report generated. Download the artifact for details." >> $GITHUB_STEP_SUMMARY
          else
            echo "Coverage report not found." >> $GITHUB_STEP_SUMMARY
          fi

      - name: Comment coverage on PR
        if: github.event_name == 'pull_request' && always()
        uses: actions/github-script@v7
        with:
          script: |
            const fs = require('fs');
            let body = '## Test Coverage Report\n\n';

            try {
              const summary = JSON.parse(fs.readFileSync('coverage/coverage-summary.json', 'utf8'));
              const total = summary.total;
              const fmt = (v) => `${v.pct}%`;
              const icon = (v) => v.pct >= 80 ? '✅' : v.pct >= 60 ? '⚠️' : '❌';

              body += '| Metric | Coverage | Status |\n';
              body += '|--------|----------|--------|\n';
              body += `| Statements | ${fmt(total.statements)} | ${icon(total.statements)} |\n`;
              body += `| Branches | ${fmt(total.branches)} | ${icon(total.branches)} |\n`;
              body += `| Functions | ${fmt(total.functions)} | ${icon(total.functions)} |\n`;
              body += `| Lines | ${fmt(total.lines)} | ${icon(total.lines)} |\n`;
            } catch (e) {
              body += '_Coverage summary not available._\n';
            }

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

            const existing = comments.find(c =>
              c.user.type === 'Bot' && c.body.includes('## Test Coverage Report')
            );

            if (existing) {
              await github.rest.issues.updateComment({
                owner: context.repo.owner,
                repo: context.repo.repo,
                comment_id: existing.id,
                body,
              });
            } else {
              await github.rest.issues.createComment({
                owner: context.repo.owner,
                repo: context.repo.repo,
                issue_number: context.issue.number,
                body,
              });
            }

  admin-web-test:
    name: Admin Web Tests
    runs-on: ubuntu-latest
    defaults:
      run:
        working-directory: admin-web
    steps:
      - uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'npm'
          cache-dependency-path: admin-web/package-lock.json

      - name: Install dependencies
        run: npm ci

      - name: Type check
        run: npx tsc --noEmit

      - name: Run unit tests
        run: npx vitest run
        continue-on-error: true

      - name: Install Playwright browsers
        run: npx playwright install --with-deps chromium

      - name: Run E2E tests
        run: npx playwright test
        continue-on-error: true

  build-check:
    name: Build Check
    runs-on: ubuntu-latest
    needs: [typecheck, lint, test]
    steps:
      - uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'npm'

      - name: Install dependencies
        run: npm ci

      - name: Export web build
        run: npx expo export --platform web
        continue-on-error: true

  deploy-functions:
    name: Deploy Edge Functions
    runs-on: ubuntu-latest
    needs: [typecheck, lint, test]
    if: github.ref == 'refs/heads/main' && github.event_name == 'push'
    steps:
      - uses: actions/checkout@v4

      - name: Deploy to self-hosted Supabase
        env:
          DEPLOY_HOST: ${{ secrets.SUPABASE_DEPLOY_HOST }}
          DEPLOY_USER: ${{ secrets.SUPABASE_DEPLOY_USER }}
          DEPLOY_PATH: ${{ secrets.SUPABASE_DEPLOY_PATH }}
        run: |
          mkdir -p ~/.ssh
          echo "${{ secrets.SUPABASE_SSH_KEY }}" > ~/.ssh/deploy_key
          chmod 600 ~/.ssh/deploy_key
          ssh-keyscan -H $DEPLOY_HOST >> ~/.ssh/known_hosts 2>/dev/null

          rsync -avz --delete \
            --exclude='node_modules' \
            --exclude='.DS_Store' \
            -e "ssh -i ~/.ssh/deploy_key" \
            supabase/functions/ \
            "$DEPLOY_USER@$DEPLOY_HOST:$DEPLOY_PATH/"

          ssh -i ~/.ssh/deploy_key "$DEPLOY_USER@$DEPLOY_HOST" \
            "docker restart supabase-edge-functions"
