name: PR Labeling and Management

on:
  pull_request:
    types: [opened, synchronize, reopened, labeled, unlabeled]

permissions:
  contents: read
  pull-requests: write
  issues: write

jobs:
  label-pr:
    name: Auto-Label Pull Request
    runs-on: ubuntu-latest
    if: github.event.action == 'opened' || github.event.action == 'synchronize'
    steps:
      - name: Checkout code
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Analyze PR and add labels
        uses: actions/github-script@v7
        with:
          script: |
            const pr = context.payload.pull_request;
            
            // Get PR files
            const { data: files } = await github.rest.pulls.listFiles({
              owner: context.repo.owner,
              repo: context.repo.repo,
              pull_number: pr.number,
            });
            
            let labels = [];
            
            // Analyze file changes
            const fileTypes = {
              workflows: files.some(f => f.filename.includes('.github/workflows')),
              tests: files.some(f => f.filename.includes('test') || f.filename.includes('spec') || f.filename.includes('e2e')),
              docs: files.some(f => f.filename.includes('README') || f.filename.includes('.md') || f.filename.includes('docs/')),
              components: files.some(f => f.filename.includes('components/') || f.filename.includes('.tsx')),
              styles: files.some(f => f.filename.includes('.css') || f.filename.includes('style')),
              config: files.some(f => f.filename.match(/\.(json|yml|yaml|config\.(js|ts))$/)),
              dependencies: files.some(f => f.filename === 'package.json' || f.filename === 'package-lock.json'),
            };
            
            if (fileTypes.workflows) labels.push('workflows');
            if (fileTypes.tests) labels.push('tests');
            if (fileTypes.docs) labels.push('documentation');
            if (fileTypes.components) labels.push('ui');
            if (fileTypes.styles) labels.push('styling');
            if (fileTypes.config) labels.push('configuration');
            if (fileTypes.dependencies) labels.push('dependencies');
            
            // Size labels
            const totalChanges = files.reduce((sum, f) => sum + f.additions + f.deletions, 0);
            if (totalChanges < 50) {
              labels.push('size: small');
            } else if (totalChanges < 200) {
              labels.push('size: medium');
            } else {
              labels.push('size: large');
            }
            
            // Check PR title for type
            const title = pr.title.toLowerCase();
            if (title.match(/^fix|bug/)) labels.push('bug');
            if (title.match(/^feat|feature|add/)) labels.push('enhancement');
            if (title.match(/^refactor/)) labels.push('refactor');
            if (title.match(/^docs/)) labels.push('documentation');
            if (title.match(/^test/)) labels.push('tests');
            if (title.match(/^chore/)) labels.push('chore');
            
            // Add labels
            if (labels.length > 0) {
              try {
                await github.rest.issues.addLabels({
                  owner: context.repo.owner,
                  repo: context.repo.repo,
                  issue_number: pr.number,
                  labels: labels
                });
              } catch (e) {
                console.log('Some labels may not exist:', e.message);
              }
            }

  check-pr-description:
    name: Check PR Description
    runs-on: ubuntu-latest
    if: github.event.action == 'opened'
    steps:
      - name: Validate PR description
        uses: actions/github-script@v7
        with:
          script: |
            const pr = context.payload.pull_request;
            const body = pr.body || '';
            
            let issues = [];
            
            // Check if description is too short
            if (body.length < 50) {
              issues.push('PR description is too short. Please provide more details about the changes.');
            }
            
            // Check if description links to an issue
            if (!body.match(/#\d+|https:\/\/github\.com/)) {
              issues.push('Consider linking to a related issue using #issue_number');
            }
            
            // Check for test information
            if (body.toLowerCase().includes('test') === false && 
                !pr.labels.some(l => l.name === 'documentation')) {
              issues.push('Please mention how these changes were tested.');
            }
            
            if (issues.length > 0) {
              const issueList = issues.map(i => '- [ ] ' + i).join('\n');
              const comment = [
                '## \uD83D\uDCCB PR Description Checklist',
                '',
                'The following items could improve this PR:',
                '',
                issueList,
                '',
                '**Good PR descriptions include:**',
                '- What changes were made and why',
                '- How to test the changes',
                '- Any breaking changes or special considerations',
                '- Links to related issues',
                '- Screenshots (for UI changes)',
                '',
                'This is a friendly reminder to help maintain code quality! \uD83D\uDE0A'
              ].join('\n');
              
              await github.rest.issues.createComment({
                owner: context.repo.owner,
                repo: context.repo.repo,
                issue_number: pr.number,
                body: comment
              });
            }

  link-related-issues:
    name: Link Related Issues
    runs-on: ubuntu-latest
    if: github.event.action == 'opened'
    steps:
      - name: Find and link related issues
        uses: actions/github-script@v7
        with:
          script: |
            const pr = context.payload.pull_request;
            const body = pr.body || '';
            const title = pr.title;
            
            // Extract issue numbers from PR body
            const issueNumbers = [...body.matchAll(/#(\d+)/g)].map(m => m[1]);
            
            if (issueNumbers.length > 0) {
              const relatedList = issueNumbers.map(n => '#' + n).join(', ');
              const comment = [
                '\uD83D\uDD17 **Related Issues**',
                '',
                'This PR is related to: ' + relatedList,
                '',
                'These issues will be automatically closed when this PR is merged.'
              ].join('\n');
              
              await github.rest.issues.createComment({
                owner: context.repo.owner,
                repo: context.repo.repo,
                issue_number: pr.number,
                body: comment
              });
              
              // Add comment to related issues
              for (const issueNum of issueNumbers) {
                try {
                  await github.rest.issues.createComment({
                    owner: context.repo.owner,
                    repo: context.repo.repo,
                    issue_number: parseInt(issueNum),
                    body: '\uD83D\uDD17 Pull request #' + pr.number + ' has been created to address this issue.'
                  });
                } catch (e) {
                  console.log('Could not comment on issue #' + issueNum);
                }
              }
            }
