/**
 * HVAC Bundled Assets Standalone Test Suite
 * 
 * Tests for HVAC_Bundled_Assets class functionality without requiring live server
 * This version runs pure JavaScript testing and validation
 * 
 * @package HVAC_Community_Events
 * @since 2.0.0
 */

const { test, expect } = require('@playwright/test');
const fs = require('fs');
const path = require('path');

/**
 * Bundled Assets Standalone Test Framework
 */
class BundledAssetsStandaloneTestFramework {
    constructor() {
        this.projectRoot = path.resolve(__dirname, '..');
        this.bundleDir = path.join(this.projectRoot, 'assets', 'js', 'dist');
        this.testResults = {
            manifestTests: [],
            bundleValidationTests: [],
            securityTests: [],
            performanceTests: [],
            fallbackTests: [],
            integrationTests: []
        };
    }

    /**
     * Test Bundle File Existence and Validation
     */
    async testBundleFileValidation() {
        console.log('📁 Testing Bundle File Validation...');
        
        await test.step('Bundle files exist and have valid structure', async () => {
            const expectedBundles = [
                'hvac-core.bundle.js',
                'hvac-dashboard.bundle.js', 
                'hvac-certificates.bundle.js',
                'hvac-master.bundle.js',
                'hvac-trainer.bundle.js',
                'hvac-events.bundle.js',
                'hvac-safari-compat.bundle.js',
                'hvac-admin.bundle.js'
            ];

            const expectedChunks = [
                'trainer-profile.chunk.js',
                'event-editing.chunk.js',
                'organizers-venues.chunk.js',
                'trainer-communication.chunk.js',
                'trainer-registration.chunk.js'
            ];

            const bundleValidation = {
                bundles: {},
                chunks: {},
                totalSize: 0,
                validFiles: 0,
                invalidFiles: 0
            };

            // Check bundle files
            for (const bundleFile of expectedBundles) {
                const bundlePath = path.join(this.bundleDir, bundleFile);
                const exists = fs.existsSync(bundlePath);
                
                if (exists) {
                    const stats = fs.statSync(bundlePath);
                    const sizeKB = Math.round(stats.size / 1024);
                    const sizeMB = (stats.size / (1024 * 1024)).toFixed(2);
                    
                    bundleValidation.bundles[bundleFile] = {
                        exists: true,
                        size: stats.size,
                        sizeKB,
                        sizeMB: parseFloat(sizeMB),
                        validSize: stats.size > 0 && stats.size <= (1024 * 1024), // Under 1MB limit
                        lastModified: stats.mtime.toISOString()
                    };
                    bundleValidation.totalSize += stats.size;
                    bundleValidation.validFiles++;
                } else {
                    bundleValidation.bundles[bundleFile] = {
                        exists: false,
                        error: 'File not found'
                    };
                    bundleValidation.invalidFiles++;
                }
            }

            // Check chunk files
            for (const chunkFile of expectedChunks) {
                const chunkPath = path.join(this.bundleDir, chunkFile);
                const exists = fs.existsSync(chunkPath);
                
                if (exists) {
                    const stats = fs.statSync(chunkPath);
                    bundleValidation.chunks[chunkFile] = {
                        exists: true,
                        size: stats.size,
                        sizeKB: Math.round(stats.size / 1024)
                    };
                    bundleValidation.totalSize += stats.size;
                    bundleValidation.validFiles++;
                } else {
                    bundleValidation.chunks[chunkFile] = {
                        exists: false,
                        error: 'File not found'
                    };
                    bundleValidation.invalidFiles++;
                }
            }

            // Validate results
            expect(bundleValidation.validFiles).toBeGreaterThan(0);
            expect(bundleValidation.totalSize).toBeGreaterThan(0);
            
            // Check core bundle exists and is reasonable size
            expect(bundleValidation.bundles['hvac-core.bundle.js'].exists).toBe(true);
            expect(bundleValidation.bundles['hvac-core.bundle.js'].size).toBeGreaterThan(50000); // At least 50KB
            
            this.testResults.bundleValidationTests.push({
                test: 'Bundle file validation',
                status: 'passed',
                details: bundleValidation
            });
            
            console.log(`✅ Found ${bundleValidation.validFiles} valid bundle files`);
            console.log(`📊 Total bundle size: ${(bundleValidation.totalSize / (1024 * 1024)).toFixed(2)}MB`);
        });
    }

    /**
     * Test Security Validation Patterns
     */
    async testSecurityValidation() {
        console.log('🔒 Testing Security Validation...');
        
        await test.step('Filename security validation', async () => {
            const filenameTests = {
                validFilenames: [
                    'hvac-core.bundle.js',
                    'hvac-trainer.bundle.js', 
                    'trainer-profile.chunk.js',
                    'event-editing.chunk.js'
                ],
                invalidFilenames: [
                    'hvac-<script>.bundle.js',
                    'hvac-bundle; rm -rf /.js',
                    'hvac-bundle\'"><script>alert(1)</script>.js',
                    '../../../etc/passwd.js',
                    'hvac-bundle.js; echo "hacked" > /tmp/hack'
                ],
                validationRegex: /^[a-zA-Z0-9._-]+$/
            };

            const securityValidation = {
                validFiles: [],
                invalidFiles: [],
                validationPassed: 0,
                validationFailed: 0
            };

            // Test valid filenames
            filenameTests.validFilenames.forEach(filename => {
                const isValid = filenameTests.validationRegex.test(filename);
                if (isValid) {
                    securityValidation.validFiles.push(filename);
                    securityValidation.validationPassed++;
                } else {
                    securityValidation.invalidFiles.push({
                        filename,
                        reason: 'Failed regex validation'
                    });
                    securityValidation.validationFailed++;
                }
            });

            // Test invalid filenames  
            filenameTests.invalidFilenames.forEach(filename => {
                const isValid = filenameTests.validationRegex.test(filename);
                if (!isValid) {
                    securityValidation.invalidFiles.push({
                        filename,
                        reason: 'Correctly rejected malicious filename',
                        status: 'properly_blocked'
                    });
                    securityValidation.validationPassed++; // This is expected behavior
                } else {
                    securityValidation.validationFailed++;
                }
            });

            // All valid filenames should pass
            expect(securityValidation.validFiles.length).toBe(filenameTests.validFilenames.length);
            
            // All invalid filenames should be rejected
            const properlyBlocked = securityValidation.invalidFiles.filter(
                item => item.status === 'properly_blocked'
            ).length;
            expect(properlyBlocked).toBe(filenameTests.invalidFilenames.length);

            this.testResults.securityTests.push({
                test: 'Filename security validation',
                status: 'passed',
                details: securityValidation
            });
            
            console.log(`✅ Security validation: ${securityValidation.validationPassed} passed, ${securityValidation.validationFailed} failed`);
        });

        await test.step('File size limit validation', async () => {
            const sizeLimitTest = {
                maxSize: 1024 * 1024, // 1MB
                testFiles: [],
                oversizedFiles: [],
                validSizedFiles: []
            };

            // Check actual bundle files against size limits
            const bundleFiles = fs.readdirSync(this.bundleDir).filter(file => file.endsWith('.js'));
            
            bundleFiles.forEach(filename => {
                const filePath = path.join(this.bundleDir, filename);
                const stats = fs.statSync(filePath);
                const fileInfo = {
                    filename,
                    size: stats.size,
                    sizeMB: (stats.size / (1024 * 1024)).toFixed(2),
                    exceedsLimit: stats.size > sizeLimitTest.maxSize
                };
                
                sizeLimitTest.testFiles.push(fileInfo);
                
                if (fileInfo.exceedsLimit) {
                    sizeLimitTest.oversizedFiles.push(fileInfo);
                } else {
                    sizeLimitTest.validSizedFiles.push(fileInfo);
                }
            });

            // Most files should be under the size limit
            expect(sizeLimitTest.validSizedFiles.length).toBeGreaterThan(0);
            
            // Log any oversized files for awareness
            if (sizeLimitTest.oversizedFiles.length > 0) {
                console.log(`⚠️  Found ${sizeLimitTest.oversizedFiles.length} oversized files that would trigger fallback:`);
                sizeLimitTest.oversizedFiles.forEach(file => {
                    console.log(`   ${file.filename}: ${file.sizeMB}MB`);
                });
            }

            this.testResults.securityTests.push({
                test: 'File size limit validation',
                status: 'passed',
                details: sizeLimitTest
            });
        });
    }

    /**
     * Test Manifest Structure Validation
     */
    async testManifestStructure() {
        console.log('📋 Testing Manifest Structure...');
        
        await test.step('Manifest structure validation', async () => {
            // Create a sample manifest based on actual files
            const actualFiles = fs.readdirSync(this.bundleDir).filter(file => file.endsWith('.js') || file.endsWith('.css'));
            
            const manifestTest = {
                sampleManifest: {},
                structure: {
                    totalEntries: 0,
                    jsFiles: 0,
                    cssFiles: 0,
                    chunkFiles: 0,
                    bundleFiles: 0
                },
                validation: {
                    isValidJSON: true,
                    isValidArray: false, // Manifest should be object, not array
                    hasRequiredEntries: false
                }
            };

            // Build sample manifest from actual files
            actualFiles.forEach(filename => {
                const keyName = filename.replace('.bundle', '').replace('.chunk', '');
                manifestTest.sampleManifest[keyName] = filename;
                manifestTest.structure.totalEntries++;
                
                if (filename.endsWith('.js')) {
                    manifestTest.structure.jsFiles++;
                }
                if (filename.endsWith('.css')) {
                    manifestTest.structure.cssFiles++;
                }
                if (filename.includes('.chunk.')) {
                    manifestTest.structure.chunkFiles++;
                } else if (filename.includes('.bundle.')) {
                    manifestTest.structure.bundleFiles++;
                }
            });

            // Validate manifest structure
            manifestTest.validation.isValidArray = Array.isArray(manifestTest.sampleManifest);
            manifestTest.validation.hasRequiredEntries = manifestTest.structure.totalEntries > 0;

            // Test JSON serialization
            try {
                const jsonString = JSON.stringify(manifestTest.sampleManifest);
                const parsed = JSON.parse(jsonString);
                manifestTest.validation.isValidJSON = typeof parsed === 'object' && parsed !== null;
            } catch (error) {
                manifestTest.validation.isValidJSON = false;
            }

            // Validate results
            expect(manifestTest.validation.isValidJSON).toBe(true);
            expect(manifestTest.validation.isValidArray).toBe(false); // Should be object
            expect(manifestTest.validation.hasRequiredEntries).toBe(true);
            expect(manifestTest.structure.bundleFiles).toBeGreaterThan(0);

            this.testResults.manifestTests.push({
                test: 'Manifest structure validation',
                status: 'passed',
                details: manifestTest
            });
            
            console.log(`✅ Manifest validation: ${manifestTest.structure.totalEntries} entries, ${manifestTest.structure.bundleFiles} bundles, ${manifestTest.structure.chunkFiles} chunks`);
        });
    }

    /**
     * Test Performance Characteristics
     */
    async testPerformanceCharacteristics() {
        console.log('⏱️ Testing Performance Characteristics...');
        
        await test.step('Bundle loading performance simulation', async () => {
            const performanceTest = {
                bundles: {},
                loadTimeSimulation: {},
                performanceThresholds: {
                    maxLoadTime: 5000, // 5 seconds
                    optimalLoadTime: 2000, // 2 seconds
                    criticalSize: 500000 // 500KB
                }
            };

            const bundleFiles = fs.readdirSync(this.bundleDir).filter(file => file.endsWith('.bundle.js'));
            
            bundleFiles.forEach(filename => {
                const filePath = path.join(this.bundleDir, filename);
                const stats = fs.statSync(filePath);
                
                // Simulate load time based on file size (rough approximation)
                const simulatedLoadTime = Math.max(200, (stats.size / 1024) * 5); // ~5ms per KB
                
                const bundlePerf = {
                    filename,
                    size: stats.size,
                    sizeKB: Math.round(stats.size / 1024),
                    simulatedLoadTime: Math.round(simulatedLoadTime),
                    exceedsOptimalTime: simulatedLoadTime > performanceTest.performanceThresholds.optimalLoadTime,
                    exceedsMaxTime: simulatedLoadTime > performanceTest.performanceThresholds.maxLoadTime,
                    isCriticalSize: stats.size > performanceTest.performanceThresholds.criticalSize
                };
                
                performanceTest.bundles[filename] = bundlePerf;
                
                // Categorize into performance groups
                if (bundlePerf.exceedsMaxTime) {
                    performanceTest.loadTimeSimulation.slow = performanceTest.loadTimeSimulation.slow || [];
                    performanceTest.loadTimeSimulation.slow.push(bundlePerf);
                } else if (bundlePerf.exceedsOptimalTime) {
                    performanceTest.loadTimeSimulation.moderate = performanceTest.loadTimeSimulation.moderate || [];
                    performanceTest.loadTimeSimulation.moderate.push(bundlePerf);
                } else {
                    performanceTest.loadTimeSimulation.fast = performanceTest.loadTimeSimulation.fast || [];
                    performanceTest.loadTimeSimulation.fast.push(bundlePerf);
                }
            });

            // Performance assertions
            const totalBundles = Object.keys(performanceTest.bundles).length;
            const slowBundles = performanceTest.loadTimeSimulation.slow ? performanceTest.loadTimeSimulation.slow.length : 0;
            
            expect(totalBundles).toBeGreaterThan(0);
            expect(slowBundles).toBeLessThan(totalBundles); // Most bundles should not be slow

            this.testResults.performanceTests.push({
                test: 'Bundle loading performance',
                status: 'passed',
                details: performanceTest
            });
            
            console.log(`✅ Performance test: ${totalBundles} bundles analyzed, ${slowBundles} potentially slow`);
        });
    }

    /**
     * Test Integration Patterns
     */
    async testIntegrationPatterns() {
        console.log('🔗 Testing Integration Patterns...');
        
        await test.step('WordPress integration pattern validation', async () => {
            const integrationTest = {
                hooks: [
                    { name: 'wp_enqueue_scripts', callback: 'enqueue_bundled_assets', context: 'frontend' },
                    { name: 'admin_enqueue_scripts', callback: 'enqueue_admin_bundled_assets', context: 'admin' },
                    { name: 'wp_head', callback: 'add_bundle_preload_hints', context: 'frontend' }
                ],
                bundleMapping: {
                    'hvac-core': ['trainer-dashboard', 'certificate-page', 'master-trainer-page'],
                    'hvac-dashboard': ['trainer-dashboard'],
                    'hvac-certificates': ['certificate-page'],
                    'hvac-master': ['master-trainer-page'],
                    'hvac-trainer': ['trainer-page'],
                    'hvac-events': ['event-page'],
                    'hvac-admin': ['wp-admin']
                },
                localizationData: {
                    objectName: 'hvacBundleData',
                    securityConfig: {
                        report_errors: true,
                        error_endpoint: '/wp-json/hvac/v1/bundle-errors',
                        performance_monitoring: true,
                        max_load_time: 5000,
                        retry_attempts: 2
                    }
                }
            };

            // Validate hook structure
            expect(integrationTest.hooks).toHaveLength(3);
            expect(integrationTest.hooks.find(h => h.name === 'wp_enqueue_scripts')).toBeDefined();

            // Validate bundle mapping
            const coreContexts = integrationTest.bundleMapping['hvac-core'];
            expect(coreContexts).toContain('trainer-dashboard');
            expect(coreContexts).toContain('certificate-page');

            // Validate security configuration
            expect(integrationTest.localizationData.securityConfig.report_errors).toBe(true);
            expect(integrationTest.localizationData.securityConfig.max_load_time).toBe(5000);

            this.testResults.integrationTests.push({
                test: 'WordPress integration patterns',
                status: 'passed',
                details: integrationTest
            });
            
            console.log('✅ Integration patterns validated');
        });
    }

    /**
     * Run all standalone tests
     */
    async runAllTests() {
        console.log('🚀 Starting Bundled Assets Standalone Test Suite...');
        
        await this.testBundleFileValidation();
        await this.testSecurityValidation();
        await this.testManifestStructure();
        await this.testPerformanceCharacteristics();
        await this.testIntegrationPatterns();
        
        return this.generateTestReport();
    }

    /**
     * Generate comprehensive test report
     */
    generateTestReport() {
        const totalTests = Object.values(this.testResults).flat().length;
        const passedTests = Object.values(this.testResults).flat().filter(test => test.status === 'passed').length;
        
        const report = {
            summary: {
                totalTests,
                passedTests,
                failedTests: totalTests - passedTests,
                passRate: totalTests > 0 ? ((passedTests / totalTests) * 100).toFixed(1) + '%' : '0%'
            },
            categories: {
                manifestTests: this.testResults.manifestTests.length,
                bundleValidationTests: this.testResults.bundleValidationTests.length,
                securityTests: this.testResults.securityTests.length,
                performanceTests: this.testResults.performanceTests.length,
                fallbackTests: this.testResults.fallbackTests.length,
                integrationTests: this.testResults.integrationTests.length
            },
            details: this.testResults,
            timestamp: new Date().toISOString(),
            projectRoot: this.projectRoot,
            bundleDirectory: this.bundleDir
        };
        
        console.log('\n📊 BUNDLED ASSETS STANDALONE TEST REPORT');
        console.log('==========================================');
        console.log(`Total Tests: ${report.summary.totalTests}`);
        console.log(`Passed: ${report.summary.passedTests}`);
        console.log(`Failed: ${report.summary.failedTests}`);
        console.log(`Pass Rate: ${report.summary.passRate}`);
        console.log('\nTest Categories:');
        Object.entries(report.categories).forEach(([category, count]) => {
            console.log(`  ${category}: ${count} tests`);
        });
        console.log(`\nBundle Directory: ${this.bundleDir}`);
        
        return report;
    }
}

// Test Suite Execution
test.describe('HVAC Bundled Assets Standalone Tests', () => {
    test('Execute all bundled assets standalone functionality tests', async () => {
        const testFramework = new BundledAssetsStandaloneTestFramework();
        
        // Run comprehensive test suite
        const report = await testFramework.runAllTests();
        
        // Assert overall test success
        expect(report.summary.passedTests).toBeGreaterThan(0);
        expect(report.summary.failedTests).toBe(0);
        expect(parseFloat(report.summary.passRate)).toBe(100.0);
        
        console.log('✅ All Bundled Assets Standalone Tests Completed Successfully');
    });
});