name: Auto Merge

on:
  pull_request_review:
    types: [submitted]
  check_suite:
    types: [completed]
  workflow_run:
    workflows: ["CI/CD"]
    types: [completed]

permissions:
  contents: write
  pull-requests: write

jobs:
  auto-merge:
    name: Auto Merge PR
    runs-on: ubuntu-latest
    if: >
      ${{
        (github.event_name == 'pull_request_review' && github.event.review.state == 'approved') ||
        (github.event_name == 'workflow_run' && github.event.workflow_run.conclusion == 'success')
      }}
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Check PR status and merge
        uses: actions/github-script@v7
        with:
          github-token: ${{ secrets.GITHUB_TOKEN }}
          script: |
            // Get PR number from event
            let prNumber;
            
            if (context.payload.pull_request) {
              prNumber = context.payload.pull_request.number;
            } else if (context.payload.workflow_run) {
              // Get PR from workflow run
              const { data: prs } = await github.rest.pulls.list({
                owner: context.repo.owner,
                repo: context.repo.repo,
                state: 'open',
                head: `${context.repo.owner}:${context.payload.workflow_run.head_branch}`
              });
              if (prs.length === 0) {
                console.log('No open PR found for this branch');
                return;
              }
              prNumber = prs[0].number;
            } else {
              console.log('Could not determine PR number');
              return;
            }
            
            console.log(`Checking PR #${prNumber}`);
            
            // Get PR details
            const { data: pr } = await github.rest.pulls.get({
              owner: context.repo.owner,
              repo: context.repo.repo,
              pull_number: prNumber
            });
            
            if (pr.state !== 'open') {
              console.log('PR is not open');
              return;
            }
            
            if (pr.draft) {
              console.log('PR is still in draft');
              return;
            }
            
            // Check if PR is approved
            const { data: reviews } = await github.rest.pulls.listReviews({
              owner: context.repo.owner,
              repo: context.repo.repo,
              pull_number: prNumber
            });
            
            const latestReviews = {};
            for (const review of reviews) {
              latestReviews[review.user.login] = review.state;
            }
            
            const hasApproval = Object.values(latestReviews).includes('APPROVED');
            const hasRequestChanges = Object.values(latestReviews).includes('CHANGES_REQUESTED');
            
            if (!hasApproval) {
              console.log('PR has not been approved yet');
              return;
            }
            
            if (hasRequestChanges) {
              console.log('PR has requested changes');
              return;
            }
            
            // Check CI status
            const { data: checks } = await github.rest.checks.listForRef({
              owner: context.repo.owner,
              repo: context.repo.repo,
              ref: pr.head.sha
            });
            
            const requiredChecks = ['Lint Code', 'Build Application', 'E2E Tests'];
            const checkStatuses = {};
            
            for (const check of checks.check_runs) {
              checkStatuses[check.name] = check.conclusion;
            }
            
            console.log('Check statuses:', checkStatuses);
            
            // Wait for all required checks to pass
            const allChecksPassed = requiredChecks.every(checkName => 
              checkStatuses[checkName] === 'success' || checkStatuses[checkName] === 'skipped'
            );
            
            if (!allChecksPassed) {
              console.log('Not all required checks have passed');
              
              // Check if any checks failed
              const anyChecksFailed = Object.values(checkStatuses).some(status => 
                status === 'failure'
              );
              
              if (anyChecksFailed) {
                console.log('Some checks failed, not merging');
                return;
              }
              
              console.log('Checks are still running, will retry later');
              return;
            }
            
            console.log('All conditions met, merging PR');
            
            // Add comment before merging
            await github.rest.issues.createComment({
              owner: context.repo.owner,
              repo: context.repo.repo,
              issue_number: prNumber,
              body: '✅ All checks passed and PR is approved! Auto-merging and cleaning up branch.'
            });
            
            try {
              // Merge the PR
              await github.rest.pulls.merge({
                owner: context.repo.owner,
                repo: context.repo.repo,
                pull_number: prNumber,
                merge_method: 'squash',
                commit_title: `${pr.title} (#${prNumber})`,
                commit_message: pr.body || ''
              });
              
              console.log('PR merged successfully');
              
              // Delete the branch
              try {
                await github.rest.git.deleteRef({
                  owner: context.repo.owner,
                  repo: context.repo.repo,
                  ref: `heads/${pr.head.ref}`
                });
                console.log(`Branch ${pr.head.ref} deleted successfully`);
              } catch (deleteError) {
                console.log('Could not delete branch:', deleteError.message);
                // Don't fail the workflow if branch deletion fails
              }
              
            } catch (mergeError) {
              console.error('Failed to merge PR:', mergeError.message);
              
              // Post comment about merge failure
              await github.rest.issues.createComment({
                owner: context.repo.owner,
                repo: context.repo.repo,
                issue_number: prNumber,
                body: `❌ Auto-merge failed: ${mergeError.message}\n\nPlease merge manually.`
              });
            }
