/**
 * Global Test Teardown for HVAC Testing Framework
 * 
 * Runs once after all tests to:
 * - Clean up test data and artifacts
 * - Generate final reports
 * - Archive screenshots and videos
 * - Display test summary
 * 
 * @package HVAC_Community_Events
 * @version 2.0.0
 * @created 2025-08-27
 */

const ConfigManager = require('../core/ConfigManager');
const AuthManager = require('../core/AuthManager');
const WordPressUtils = require('../utils/WordPressUtils');
const ScreenshotManager = require('../utils/ScreenshotManager');
const fs = require('fs').promises;
const path = require('path');

async function globalTeardown(config) {
    console.log('\n🏁 HVAC Testing Framework - Global Teardown');
    console.log('='.repeat(50));
    
    const startTime = Date.now();
    const configManager = ConfigManager;
    const authManager = AuthManager;
    const wpUtils = new WordPressUtils();
    const screenshotManager = new ScreenshotManager();
    
    try {
        // 1. Clean Up Test Data
        console.log('\n🧹 1. Cleaning Up Test Data');
        
        const environment = configManager.getEnvironment();
        
        if (configManager.get('testData.cleanupAfterTests') && environment !== 'staging') {
            try {
                // Clean up WordPress test data
                const testIds = await getTestIds();
                for (const testId of testIds) {
                    await wpUtils.cleanupTestData(testId);
                }
                
                console.log(`   ✅ Cleaned up ${testIds.length} test datasets`);
            } catch (error) {
                console.warn('   ⚠️ Test data cleanup failed:', error.message);
            }
        } else {
            console.log('   ℹ️ Skipping test data cleanup (staging environment)');
        }
        
        // 2. Authentication State Management
        console.log('\n🔐 2. Authentication State Management');
        
        // Get auth status before cleanup
        const authStatus = await authManager.getAuthStatus();
        console.log(`   📊 Storage states: ${Object.keys(authStatus).length} roles`);
        
        // Clear validation cache
        authManager.clearValidationCache();
        console.log('   ✅ Validation cache cleared');
        
        // Clean up old storage states if configured
        if (environment === 'local') {
            // Only clean on local environment
            const oldStatesCount = await cleanOldStorageStates();
            if (oldStatesCount > 0) {
                console.log(`   🗑️ Removed ${oldStatesCount} old storage states`);
            }
        }
        
        // 3. Generate Screenshot Reports
        console.log('\n📸 3. Processing Screenshots and Media');
        
        try {
            // Generate screenshot report
            const screenshotReport = await screenshotManager.generateReport();
            if (screenshotReport) {
                console.log(`   📊 Screenshot report: ${screenshotReport.totalScreenshots} files`);
            }
            
            // Create screenshot gallery
            const galleryPath = await screenshotManager.createGallery('HVAC Test Results');
            if (galleryPath) {
                console.log(`   🖼️ Screenshot gallery: ${galleryPath}`);
            }
            
            // Clean up old screenshots if configured
            const daysToKeep = 7;
            await screenshotManager.cleanup(daysToKeep);
            
        } catch (error) {
            console.warn('   ⚠️ Screenshot processing failed:', error.message);
        }
        
        // 4. Generate Final Test Report
        console.log('\n📊 4. Generating Final Reports');
        
        try {
            const finalReport = await generateFinalReport(startTime);
            const reportPath = path.resolve('./test-results/final-report.json');
            await fs.writeFile(reportPath, JSON.stringify(finalReport, null, 2));
            
            console.log(`   ✅ Final report: ${reportPath}`);
            
            // Generate HTML summary
            const htmlReport = await generateHTMLReport(finalReport);
            const htmlPath = path.resolve('./test-results/summary.html');
            await fs.writeFile(htmlPath, htmlReport);
            
            console.log(`   📄 HTML report: ${htmlPath}`);
            
        } catch (error) {
            console.warn('   ⚠️ Report generation failed:', error.message);
        }
        
        // 5. Archive Test Artifacts
        console.log('\n📦 5. Archiving Test Artifacts');
        
        try {
            await archiveTestArtifacts();
            console.log('   ✅ Test artifacts archived');
        } catch (error) {
            console.warn('   ⚠️ Archiving failed:', error.message);
        }
        
        // 6. WordPress Cleanup (if safe)
        console.log('\n⚙️ 6. WordPress Environment Cleanup');
        
        if (environment === 'local' || environment === 'docker') {
            try {
                // Clear cache one final time
                await wpUtils.clearCache();
                console.log('   ✅ Final cache clear');
                
            } catch (error) {
                console.warn('   ⚠️ WordPress cleanup failed:', error.message);
            }
        } else {
            console.log('   ℹ️ Skipping WordPress cleanup (staging environment)');
        }
        
        // 7. Display Final Summary
        console.log('\n📋 7. Test Session Summary');
        
        await displayTestSummary();
        
        // 8. Final Teardown Report
        const duration = ((Date.now() - startTime) / 1000).toFixed(2);
        console.log('\n' + '='.repeat(50));
        console.log('✅ Global Teardown Complete');
        console.log(`⏱️  Teardown Duration: ${duration}s`);
        console.log(`🌍 Environment: ${environment}`);
        console.log('='.repeat(50) + '\n');
        
    } catch (error) {
        console.error('\n❌ Global Teardown Failed');
        console.error('Error:', error.message);
        console.error('='.repeat(50) + '\n');
        // Don't throw - teardown failures shouldn't fail the test suite
    }
}

/**
 * Get list of test IDs for cleanup
 */
async function getTestIds() {
    try {
        const testResults = await fs.readFile('./test-results/test-metrics.jsonl', 'utf8');
        const lines = testResults.trim().split('\n');
        const testIds = lines
            .map(line => JSON.parse(line))
            .map(test => test.testId)
            .filter(id => id.startsWith('hvac-test-'));
        
        return [...new Set(testIds)]; // Remove duplicates
    } catch (error) {
        return [];
    }
}

/**
 * Clean old storage states
 */
async function cleanOldStorageStates() {
    try {
        const storageStatesDir = path.resolve(__dirname, '../fixtures/storage-states');
        const files = await fs.readdir(storageStatesDir);
        const cutoffDate = new Date();
        cutoffDate.setDate(cutoffDate.getDate() - 7);
        
        let deletedCount = 0;
        for (const file of files) {
            if (file.endsWith('.json')) {
                const filePath = path.join(storageStatesDir, file);
                const stats = await fs.stat(filePath);
                
                if (stats.mtime < cutoffDate) {
                    await fs.unlink(filePath);
                    deletedCount++;
                }
            }
        }
        
        return deletedCount;
    } catch (error) {
        return 0;
    }
}

/**
 * Generate comprehensive final report
 */
async function generateFinalReport(startTime) {
    const report = {
        timestamp: new Date().toISOString(),
        environment: ConfigManager.getEnvironment(),
        teardownDuration: Date.now() - startTime,
        framework: {
            version: '2.0.0',
            features: ConfigManager.get('features')
        }
    };
    
    // Add test metrics if available
    try {
        const metricsFile = './test-results/test-metrics.jsonl';
        const metricsData = await fs.readFile(metricsFile, 'utf8');
        const metrics = metricsData.trim().split('\n').map(line => JSON.parse(line));
        
        report.testMetrics = {
            totalTests: metrics.length,
            passed: metrics.filter(t => t.passed).length,
            failed: metrics.filter(t => !t.passed).length,
            categories: groupBy(metrics, 'category'),
            avgDuration: metrics.reduce((sum, t) => sum + t.duration, 0) / metrics.length
        };
    } catch (error) {
        report.testMetrics = { error: 'Metrics not available' };
    }
    
    return report;
}

/**
 * Generate HTML report
 */
async function generateHTMLReport(report) {
    const testMetrics = report.testMetrics || {};
    const passRate = testMetrics.totalTests ? 
        ((testMetrics.passed / testMetrics.totalTests) * 100).toFixed(1) : 'N/A';
    
    return `
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>HVAC Test Results Summary</title>
        <style>
            body { font-family: system-ui, sans-serif; margin: 0; padding: 20px; background: #f5f5f5; }
            .header { text-align: center; background: white; padding: 30px; border-radius: 8px; margin-bottom: 20px; }
            .metrics { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 20px; margin: 20px 0; }
            .metric { background: white; padding: 20px; border-radius: 8px; text-align: center; }
            .metric h3 { margin: 0; color: #333; }
            .metric .value { font-size: 2em; font-weight: bold; margin: 10px 0; }
            .passed { color: #28a745; }
            .failed { color: #dc3545; }
            .info { background: white; padding: 20px; border-radius: 8px; margin-top: 20px; }
            pre { background: #f8f9fa; padding: 15px; border-radius: 4px; overflow-x: auto; }
        </style>
    </head>
    <body>
        <div class="header">
            <h1>🧪 HVAC Testing Framework Results</h1>
            <p><strong>Environment:</strong> ${report.environment}</p>
            <p><strong>Generated:</strong> ${new Date(report.timestamp).toLocaleString()}</p>
        </div>
        
        <div class="metrics">
            <div class="metric">
                <h3>Total Tests</h3>
                <div class="value">${testMetrics.totalTests || 0}</div>
            </div>
            <div class="metric">
                <h3>Passed</h3>
                <div class="value passed">${testMetrics.passed || 0}</div>
            </div>
            <div class="metric">
                <h3>Failed</h3>
                <div class="value failed">${testMetrics.failed || 0}</div>
            </div>
            <div class="metric">
                <h3>Pass Rate</h3>
                <div class="value">${passRate}%</div>
            </div>
        </div>
        
        <div class="info">
            <h2>📊 Detailed Report</h2>
            <pre>${JSON.stringify(report, null, 2)}</pre>
        </div>
    </body>
    </html>
    `;
}

/**
 * Archive test artifacts
 */
async function archiveTestArtifacts() {
    const archiveDir = path.resolve('./test-results/archives');
    const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
    const archiveName = `test-session-${timestamp}`;
    const sessionArchive = path.join(archiveDir, archiveName);
    
    await fs.mkdir(sessionArchive, { recursive: true });
    
    // Copy important files to archive
    const filesToArchive = [
        './test-results/final-report.json',
        './test-results/summary.html',
        './test-results/setup-report.json'
    ];
    
    for (const file of filesToArchive) {
        try {
            const filename = path.basename(file);
            const sourcePath = path.resolve(file);
            const destPath = path.join(sessionArchive, filename);
            
            await fs.copyFile(sourcePath, destPath);
        } catch (error) {
            // File might not exist, continue
        }
    }
}

/**
 * Display test session summary
 */
async function displayTestSummary() {
    try {
        const metricsFile = './test-results/test-metrics.jsonl';
        const metricsData = await fs.readFile(metricsFile, 'utf8');
        const metrics = metricsData.trim().split('\n').map(line => JSON.parse(line));
        
        const totalTests = metrics.length;
        const passed = metrics.filter(t => t.passed).length;
        const failed = metrics.filter(t => !t.passed).length;
        const passRate = ((passed / totalTests) * 100).toFixed(1);
        
        console.log(`   📊 Total Tests: ${totalTests}`);
        console.log(`   ✅ Passed: ${passed}`);
        console.log(`   ❌ Failed: ${failed}`);
        console.log(`   📈 Pass Rate: ${passRate}%`);
        
        if (failed > 0) {
            console.log('\n   ❌ Failed Tests:');
            metrics
                .filter(t => !t.passed)
                .slice(0, 5) // Show first 5 failures
                .forEach(t => console.log(`     - ${t.title}`));
            
            if (failed > 5) {
                console.log(`     ... and ${failed - 5} more`);
            }
        }
        
    } catch (error) {
        console.log('   ℹ️ No test metrics available');
    }
}

/**
 * Helper function to group by property
 */
function groupBy(array, property) {
    return array.reduce((groups, item) => {
        const key = item[property] || 'unknown';
        groups[key] = (groups[key] || 0) + 1;
        return groups;
    }, {});
}

module.exports = globalTeardown;