name: Deployment & Monitoring

on:
  push:
    branches:
      - main
      - master
  release:
    types: [published]
  workflow_dispatch:
    inputs:
      environment:
        description: 'Deployment environment'
        required: true
        type: choice
        options:
          - staging
          - production

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

jobs:
  pre-deployment-check:
    name: Pre-Deployment Validation
    runs-on: ubuntu-latest
    defaults:
      run:
        working-directory: frontends/nextjs
    steps:
      - name: Checkout code
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Setup Bun
        uses: oven-sh/setup-bun@v2
        with:
          bun-version: '1.3.4'

      - name: Cache Bun dependencies
        uses: actions/cache@v4
        with:
          key: bun-deps-${{ runner.os }}-${{ hashFiles('bun.lock') }}
          path: |
            frontends/nextjs/node_modules
            ~/.bun
          restore-keys: bun-deps-${{ runner.os }}-

      - name: Install dependencies
        run: bun install --frozen-lockfile

      - name: Generate Prisma Client
        run: bun run db:generate
        env:
          DATABASE_URL: file:./dev.db

      - name: Validate database schema
        run: bunx prisma validate

      - name: Check for breaking changes
        id: breaking-changes
        uses: actions/github-script@v7
        with:
          script: |
            // Get recent commits
            const commits = await github.rest.repos.listCommits({
              owner: context.repo.owner,
              repo: context.repo.repo,
              per_page: 10
            });
            
            let hasBreaking = false;
            let breakingChanges = [];
            
            for (const commit of commits.data) {
              const message = commit.commit.message.toLowerCase();
              if (message.includes('breaking') || message.includes('breaking:')) {
                hasBreaking = true;
                breakingChanges.push({
                  sha: commit.sha.substring(0, 7),
                  message: commit.commit.message.split('\n')[0]
                });
              }
            }
            
            core.setOutput('has_breaking', hasBreaking);
            
            if (hasBreaking) {
              console.log('⚠️ Breaking changes detected:');
              breakingChanges.forEach(c => console.log(`  - ${c.sha}: ${c.message}`));
            }
            
            return { hasBreaking, breakingChanges };

      - name: Run security audit
        run: bun audit --audit-level=moderate
        continue-on-error: true

      - name: Check package size
        run: |
          bun run build
          du -sh dist/
          
          # Check if dist is larger than 10MB
          SIZE=$(du -sm dist/ | cut -f1)
          if [ $SIZE -gt 10 ]; then
            echo "⚠️ Warning: Build size is ${SIZE}MB (>10MB). Consider optimizing."
          else
            echo "✅ Build size is ${SIZE}MB"
          fi

      - name: Validate environment configuration
        run: |
          echo "Checking for required environment variables..."
          
          # Check .env.example exists
          if [ ! -f .env.example ]; then
            echo "❌ .env.example not found"
            exit 1
          fi
          
          echo "✅ Environment configuration validated"

  deployment-summary:
    name: Create Deployment Summary
    runs-on: ubuntu-latest
    needs: pre-deployment-check
    steps:
      - name: Checkout code
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Generate deployment notes
        uses: actions/github-script@v7
        with:
          script: |
            const fs = require('fs');
            
            // Get commits since last release
            let commits = [];
            try {
              const result = await github.rest.repos.listCommits({
                owner: context.repo.owner,
                repo: context.repo.repo,
                per_page: 20
              });
              commits = result.data;
            } catch (e) {
              console.log('Could not fetch commits:', e.message);
            }
            
            // Categorize commits
            const features = [];
            const fixes = [];
            const breaking = [];
            const other = [];
            
            for (const commit of commits) {
              const message = commit.commit.message;
              const firstLine = message.split('\n')[0];
              const sha = commit.sha.substring(0, 7);
              
              if (message.toLowerCase().includes('breaking')) {
                breaking.push(`- ${firstLine} (${sha})`);
              } else if (firstLine.match(/^feat|^feature|^add/i)) {
                features.push(`- ${firstLine} (${sha})`);
              } else if (firstLine.match(/^fix|^bug/i)) {
                fixes.push(`- ${firstLine} (${sha})`);
              } else {
                other.push(`- ${firstLine} (${sha})`);
              }
            }
            
            // Create deployment notes
            let notes = `# Deployment Summary\n\n`;
            notes += `**Date:** ${new Date().toISOString()}\n`;
            notes += `**Branch:** ${context.ref}\n`;
            notes += `**Commit:** ${context.sha.substring(0, 7)}\n\n`;
            
            if (breaking.length > 0) {
              notes += `## ⚠️ Breaking Changes\n\n${breaking.join('\n')}\n\n`;
            }
            
            if (features.length > 0) {
              notes += `## ✨ New Features\n\n${features.slice(0, 10).join('\n')}\n\n`;
            }
            
            if (fixes.length > 0) {
              notes += `## 🐛 Bug Fixes\n\n${fixes.slice(0, 10).join('\n')}\n\n`;
            }
            
            if (other.length > 0) {
              notes += `## 🔧 Other Changes\n\n${other.slice(0, 5).join('\n')}\n\n`;
            }
            
            notes += `---\n`;
            notes += `**Total commits:** ${commits.length}\n\n`;
            notes += `**@copilot** Review the deployment for any potential issues.`;
            
            console.log(notes);
            
            // Save to file for artifact
            fs.writeFileSync('DEPLOYMENT_NOTES.md', notes);

      - name: Upload deployment notes
        uses: actions/upload-artifact@v4
        with:
          name: deployment-notes
          path: DEPLOYMENT_NOTES.md
          retention-days: 90

  post-deployment-health:
    name: Post-Deployment Health Check
    runs-on: ubuntu-latest
    needs: deployment-summary
    if: github.event_name == 'push' || github.event_name == 'release'
    defaults:
      run:
        working-directory: frontends/nextjs
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Setup Bun
        uses: oven-sh/setup-bun@v2
        with:
          bun-version: '1.3.4'

      - name: Cache Bun dependencies
        uses: actions/cache@v4
        with:
          key: bun-deps-${{ runner.os }}-${{ hashFiles('bun.lock') }}
          path: |
            frontends/nextjs/node_modules
            ~/.bun
          restore-keys: bun-deps-${{ runner.os }}-

      - name: Install dependencies
        run: bun install --frozen-lockfile

      - name: Generate Prisma Client
        run: bun run db:generate
        env:
          DATABASE_URL: file:./dev.db

      - name: Verify build integrity
        run: |
          bun run build
          
          # Check critical files exist
          if [ ! -f "dist/index.html" ]; then
            echo "❌ Critical file missing: dist/index.html"
            exit 1
          fi
          
          echo "✅ Build integrity verified"

      - name: Create health check report
        uses: actions/github-script@v7
        with:
          script: |
            const report = `## 🏥 Post-Deployment Health Check
            
            **Status:** ✅ Healthy
            **Timestamp:** ${new Date().toISOString()}
            **Environment:** ${context.ref}
            
            ### Checks Performed
            - ✅ Build integrity verified
            - ✅ Database schema valid
            - ✅ Dependencies installed
            - ✅ Critical files present
            
            ### Monitoring
            - Monitor application logs for errors
            - Check database connection stability  
            - Verify user authentication flows
            - Test multi-tenant isolation
            - Validate package system operations
            
            **@copilot** Assist with monitoring and troubleshooting if issues arise.
            `;
            
            console.log(report);

  create-deployment-issue:
    name: Track Deployment
    runs-on: ubuntu-latest
    needs: [pre-deployment-check, post-deployment-health]
    if: github.event_name == 'release'
    steps:
      - name: Create deployment tracking issue
        uses: actions/github-script@v7
        with:
          script: |
            const release = context.payload.release;
            
            const issueBody = `## 🚀 Deployment Tracking: ${release.name || release.tag_name}
            
            **Release:** [${release.tag_name}](${release.html_url})
            **Published:** ${release.published_at}
            **Published by:** @${release.author.login}
            
            ### Deployment Checklist
            
            - [x] Pre-deployment validation completed
            - [x] Build successful
            - [x] Health checks passed
            - [ ] Database migrations applied (if any)
            - [ ] Smoke tests completed
            - [ ] User acceptance testing
            - [ ] Production monitoring confirmed
            - [ ] Documentation updated
            
            ### Post-Deployment Monitoring
            
            Monitor the following for 24-48 hours:
            - Application error rates
            - Database query performance
            - User authentication success rate
            - Multi-tenant operations
            - Package system functionality
            - Memory and CPU usage
            
            ### Rollback Plan
            
            If critical issues are detected:
            1. Document the issue with logs and reproduction steps
            2. Notify team members
            3. Execute rollback: \`git revert ${context.sha}\`
            4. Deploy previous stable version
            5. Create incident report
            
            **@copilot** Monitor this deployment and assist with any issues that arise.
            
            ---
            
            Close this issue once deployment is verified stable after 48 hours.`;
            
            const issue = await github.rest.issues.create({
              owner: context.repo.owner,
              repo: context.repo.repo,
              title: `Deployment: ${release.tag_name}`,
              body: issueBody,
              labels: ['deployment', 'monitoring']
            });
            
            console.log(`Created tracking issue: #${issue.data.number}`);

  dependency-audit:
    name: Security Audit
    runs-on: ubuntu-latest
    needs: pre-deployment-check
    defaults:
      run:
        working-directory: frontends/nextjs
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Setup Bun
        uses: oven-sh/setup-bun@v2
        with:
          bun-version: '1.3.4'

      - name: Cache Bun dependencies
        uses: actions/cache@v4
        with:
          key: bun-deps-${{ runner.os }}-${{ hashFiles('bun.lock') }}
          path: |
            frontends/nextjs/node_modules
            ~/.bun
          restore-keys: bun-deps-${{ runner.os }}-

      - name: Audit dependencies
        id: audit
        run: |
          bun audit --json > audit-report.json || true
          
          # Check for critical vulnerabilities
          CRITICAL=$(cat audit-report.json | grep -o '"critical":[0-9]*' | grep -o '[0-9]*' || echo "0")
          HIGH=$(cat audit-report.json | grep -o '"high":[0-9]*' | grep -o '[0-9]*' || echo "0")
          
          echo "critical=$CRITICAL" >> $GITHUB_OUTPUT
          echo "high=$HIGH" >> $GITHUB_OUTPUT
          
          if [ "$CRITICAL" -gt 0 ] || [ "$HIGH" -gt 0 ]; then
            echo "⚠️ Security vulnerabilities found: $CRITICAL critical, $HIGH high"
          else
            echo "✅ No critical or high security vulnerabilities"
          fi

      - name: Create security issue if vulnerabilities found
        if: steps.audit.outputs.critical > 0 || steps.audit.outputs.high > 0
        uses: actions/github-script@v7
        with:
          script: |
            const critical = ${{ steps.audit.outputs.critical }};
            const high = ${{ steps.audit.outputs.high }};
            
            const issueBody = `## 🔒 Security Audit Alert
            
            Security vulnerabilities detected in dependencies:
            - **Critical:** ${critical}
            - **High:** ${high}
            
            ### Action Required
            
            1. Review the vulnerabilities: \`bun audit\`
            2. Update affected packages: \`bun audit fix\`
            3. Test the application after updates
            4. If auto-fix doesn't work, manually update packages
            5. Consider alternatives for packages with unfixable issues
            
            ### Review Process
            
            \`\`\`bash
            # View detailed audit
            bun audit
            
            # Attempt automatic fix
            bun audit fix
            
            # Force fix (may introduce breaking changes)
            bun audit fix --force
            
            # Check results
            bun audit
            \`\`\`
            
            **@copilot** Suggest safe dependency updates to resolve these vulnerabilities.
            
            ---
            
            **Priority:** ${critical > 0 ? 'CRITICAL' : 'HIGH'}  
            **Created:** ${new Date().toISOString()}
            `;
            
            await github.rest.issues.create({
              owner: context.repo.owner,
              repo: context.repo.repo,
              title: `Security: ${critical} critical, ${high} high vulnerabilities`,
              body: issueBody,
              labels: ['security', 'dependencies', critical > 0 ? 'priority: high' : 'priority: medium']
            });
