/**
 * TestRunner - Main test execution engine
 * Runs all test suites and generates comprehensive reports
 */

class TestRunner {
    constructor() {
        this.testSuites = [];
        this.results = [];
        this.overallResults = {
            totalSuites: 0,
            passedSuites: 0,
            failedSuites: 0,
            totalTests: 0,
            passedTests: 0,
            failedTests: 0,
            skippedTests: 0,
            duration: 0,
            startTime: null,
            endTime: null
        };
    }

    /**
     * Register a test suite
     * @param {string} name - Name of the test suite
     * @param {Object} testFramework - TestFramework instance with tests
     */
    registerSuite(name, testFramework) {
        this.testSuites.push({
            name,
            framework: testFramework
        });
    }

    /**
     * Run all registered test suites
     * @returns {Promise<Object>} - Complete test results
     */
    async runAllTests() {
        console.log('🚀 Starting Test Runner...');
        console.log('='.repeat(80));

        this.overallResults.startTime = Date.now();
        this.overallResults.totalSuites = this.testSuites.length;

        for (const suite of this.testSuites) {
            console.log(`\n🏃‍♂️ Running test suite: ${suite.name}`);
            console.log('-'.repeat(60));

            try {
                const result = await suite.framework.runAll();
                this.results.push({
                    suiteName: suite.name,
                    success: result.failed === 0,
                    result: result
                });

                if (result.failed === 0) {
                    this.overallResults.passedSuites++;
                    console.log(`✅ Suite "${suite.name}" PASSED`);
                } else {
                    this.overallResults.failedSuites++;
                    console.log(`❌ Suite "${suite.name}" FAILED`);
                }

                // Aggregate test counts
                this.overallResults.totalTests += result.total;
                this.overallResults.passedTests += result.passed;
                this.overallResults.failedTests += result.failed;
                this.overallResults.skippedTests += result.skipped;

            } catch (error) {
                console.error(`💥 Suite "${suite.name}" crashed:`, error);
                this.overallResults.failedSuites++;
                this.results.push({
                    suiteName: suite.name,
                    success: false,
                    error: {
                        message: error.message,
                        stack: error.stack
                    }
                });
            }
        }

        this.overallResults.endTime = Date.now();
        this.overallResults.duration = this.overallResults.endTime - this.overallResults.startTime;

        this._printOverallSummary();
        return this.getCompleteResults();
    }

    /**
     * Run tests with HTML report generation
     * @param {HTMLElement} container - Container to render results (optional)
     * @returns {Promise<Object>} - Complete test results
     */
    async runTestsWithReport(container = null) {
        const results = await this.runAllTests();

        if (container) {
            this._renderHTMLReport(container, results);
        }

        return results;
    }

    /**
     * Get complete test results
     * @returns {Object} - All test results and metadata
     */
    getCompleteResults() {
        return {
            overall: this.overallResults,
            suites: this.results,
            summary: {
                success: this.overallResults.failedSuites === 0 && this.overallResults.failedTests === 0,
                passRate: this.overallResults.totalTests > 0
                    ? Math.round((this.overallResults.passedTests / this.overallResults.totalTests) * 100)
                    : 0,
                message: this._getOverallMessage()
            }
        };
    }

    /**
     * Print overall test summary
     * @private
     */
    _printOverallSummary() {
        console.log('\n' + '='.repeat(80));
        console.log('🏆 OVERALL TEST RESULTS');
        console.log('='.repeat(80));

        const passRate = this.overallResults.totalTests > 0
            ? Math.round((this.overallResults.passedTests / this.overallResults.totalTests) * 100)
            : 0;

        const overallSuccess = this.overallResults.failedSuites === 0 && this.overallResults.failedTests === 0;
        const statusIcon = overallSuccess ? '✅' : '❌';
        const statusText = overallSuccess ? 'ALL TESTS PASSED' : 'SOME TESTS FAILED';

        console.log(`${statusIcon} ${statusText}`);
        console.log(`\n📊 SUITE SUMMARY:`);
        console.log(`   Total Suites: ${this.overallResults.totalSuites}`);
        console.log(`   Passed Suites: ${this.overallResults.passedSuites}`);
        console.log(`   Failed Suites: ${this.overallResults.failedSuites}`);

        console.log(`\n🧪 TEST SUMMARY:`);
        console.log(`   Total Tests: ${this.overallResults.totalTests}`);
        console.log(`   Passed: ${this.overallResults.passedTests} (${passRate}%)`);
        console.log(`   Failed: ${this.overallResults.failedTests}`);
        console.log(`   Skipped: ${this.overallResults.skippedTests}`);
        console.log(`   Duration: ${this.overallResults.duration}ms`);

        // Suite breakdown
        console.log(`\n📦 DETAILED BREAKDOWN:`);
        this.results.forEach(result => {
            const icon = result.success ? '✅' : '❌';
            if (result.result) {
                console.log(`   ${icon} ${result.suiteName}: ${result.result.passed}/${result.result.total} tests`);
            } else {
                console.log(`   ${icon} ${result.suiteName}: CRASHED`);
            }
        });

        // Performance analysis
        const avgTestTime = this.overallResults.totalTests > 0
            ? Math.round(this.overallResults.duration / this.overallResults.totalTests)
            : 0;

        console.log(`\n⚡ PERFORMANCE:`);
        console.log(`   Average per test: ${avgTestTime}ms`);
        console.log(`   Total execution: ${this.overallResults.duration}ms`);

        // Architecture quality assessment
        console.log(`\n🏗️ ARCHITECTURE QUALITY:`);
        this._assessArchitectureQuality();

        console.log('='.repeat(80));
    }

    /**
     * Assess architecture quality based on test results
     * @private
     */
    _assessArchitectureQuality() {
        const coreArchTests = this.results.find(r => r.suiteName.includes('CoreArchitecture'));
        const drsTests = this.results.find(r => r.suiteName.includes('DRS'));

        if (coreArchTests && coreArchTests.success) {
            console.log('   ✅ Core Architecture: SOLID');
        } else if (coreArchTests && !coreArchTests.success) {
            console.log('   ❌ Core Architecture: NEEDS ATTENTION');
        } else {
            console.log('   ⚠️ Core Architecture: NOT TESTED');
        }

        if (drsTests && drsTests.success) {
            console.log('   ✅ DRS Modules: WELL INTEGRATED');
        } else if (drsTests && !drsTests.success) {
            console.log('   ❌ DRS Modules: INTEGRATION ISSUES');
        } else {
            console.log('   ⚠️ DRS Modules: NOT TESTED');
        }

        // Performance assessment
        if (this.overallResults.duration < 5000) { // Under 5 seconds
            console.log('   ✅ Performance: EXCELLENT');
        } else if (this.overallResults.duration < 15000) { // Under 15 seconds
            console.log('   ⚠️ Performance: ACCEPTABLE');
        } else {
            console.log('   ❌ Performance: SLOW - NEEDS OPTIMIZATION');
        }

        // Coverage assessment
        const passRate = this.overallResults.totalTests > 0
            ? (this.overallResults.passedTests / this.overallResults.totalTests)
            : 0;

        if (passRate >= 0.95) {
            console.log('   ✅ Test Coverage: EXCELLENT');
        } else if (passRate >= 0.8) {
            console.log('   ⚠️ Test Coverage: GOOD');
        } else {
            console.log('   ❌ Test Coverage: INSUFFICIENT');
        }
    }

    /**
     * Get overall result message
     * @returns {string} - Summary message
     * @private
     */
    _getOverallMessage() {
        if (this.overallResults.failedSuites === 0 && this.overallResults.failedTests === 0) {
            return '🎉 All tests passed! Architecture is solid and modules are working correctly.';
        } else if (this.overallResults.failedTests > 0 && this.overallResults.passedTests > this.overallResults.failedTests) {
            return '⚠️ Most tests passed, but some issues need attention.';
        } else {
            return '❌ Significant test failures detected. Architecture or implementation needs review.';
        }
    }

    /**
     * Render HTML report in container
     * @param {HTMLElement} container - Container element
     * @param {Object} results - Test results
     * @private
     */
    _renderHTMLReport(container, results) {
        const passRate = results.overall.passedTests > 0
            ? Math.round((results.overall.passedTests / results.overall.totalTests) * 100)
            : 0;

        const html = `
            <div class="test-report">
                <div class="report-header">
                    <h1>🧪 Test Report</h1>
                    <div class="overall-status ${results.summary.success ? 'success' : 'failure'}">
                        ${results.summary.success ? '✅' : '❌'} ${results.summary.message}
                    </div>
                </div>

                <div class="summary-cards">
                    <div class="summary-card">
                        <h3>📊 Overall</h3>
                        <div class="metric">${results.overall.totalTests} Tests</div>
                        <div class="sub-metric">${passRate}% Pass Rate</div>
                    </div>
                    <div class="summary-card">
                        <h3>✅ Passed</h3>
                        <div class="metric">${results.overall.passedTests}</div>
                        <div class="sub-metric">${results.overall.passedSuites} Suites</div>
                    </div>
                    <div class="summary-card">
                        <h3>❌ Failed</h3>
                        <div class="metric">${results.overall.failedTests}</div>
                        <div class="sub-metric">${results.overall.failedSuites} Suites</div>
                    </div>
                    <div class="summary-card">
                        <h3>⚡ Duration</h3>
                        <div class="metric">${results.overall.duration}ms</div>
                        <div class="sub-metric">${Math.round(results.overall.duration / results.overall.totalTests)}ms avg</div>
                    </div>
                </div>

                <div class="suites-breakdown">
                    <h2>📦 Test Suites</h2>
                    ${results.suites.map(suite => `
                        <div class="suite-card ${suite.success ? 'success' : 'failure'}">
                            <div class="suite-header">
                                <h3>${suite.success ? '✅' : '❌'} ${suite.suiteName}</h3>
                                ${suite.result ? `<span class="suite-stats">${suite.result.passed}/${suite.result.total} tests</span>` : '<span class="suite-error">CRASHED</span>'}
                            </div>
                            ${suite.error ? `<div class="error-details">Error: ${suite.error.message}</div>` : ''}
                            ${suite.result && suite.result.failed > 0 ? `
                                <div class="failed-tests">
                                    <strong>Failed Tests:</strong>
                                    ${suite.result.details.filter(d => d.state === 'failed').map(d =>
                                        `<div class="failed-test">${d.name}: ${d.error?.message || 'Unknown error'}</div>`
                                    ).join('')}
                                </div>
                            ` : ''}
                        </div>
                    `).join('')}
                </div>
            </div>
        `;

        container.innerHTML = html;
        this._addReportStyles();
    }

    /**
     * Add CSS styles for HTML report
     * @private
     */
    _addReportStyles() {
        if (document.getElementById('test-report-styles')) return;

        const styles = document.createElement('style');
        styles.id = 'test-report-styles';
        styles.textContent = `
            .test-report {
                font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
                max-width: 1200px;
                margin: 0 auto;
                padding: 20px;
            }

            .report-header {
                text-align: center;
                margin-bottom: 30px;
            }

            .overall-status {
                font-size: 1.2em;
                font-weight: 600;
                padding: 15px 30px;
                border-radius: 8px;
                margin-top: 15px;
            }

            .overall-status.success {
                background: linear-gradient(135deg, #e8f5e8, #f1f8e9);
                color: #2e7d32;
                border: 2px solid #4caf50;
            }

            .overall-status.failure {
                background: linear-gradient(135deg, #ffebee, #ffcdd2);
                color: #c62828;
                border: 2px solid #f44336;
            }

            .summary-cards {
                display: grid;
                grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
                gap: 20px;
                margin-bottom: 40px;
            }

            .summary-card {
                background: white;
                border-radius: 12px;
                padding: 20px;
                box-shadow: 0 4px 15px rgba(0,0,0,0.1);
                text-align: center;
                border-left: 4px solid #667eea;
            }

            .summary-card h3 {
                margin: 0 0 15px 0;
                color: #333;
                font-size: 1.1em;
            }

            .metric {
                font-size: 2.5em;
                font-weight: bold;
                color: #333;
                margin-bottom: 5px;
            }

            .sub-metric {
                color: #666;
                font-size: 0.9em;
            }

            .suites-breakdown {
                margin-top: 40px;
            }

            .suites-breakdown h2 {
                margin-bottom: 20px;
                color: #333;
            }

            .suite-card {
                background: white;
                border-radius: 8px;
                padding: 20px;
                margin-bottom: 15px;
                box-shadow: 0 2px 8px rgba(0,0,0,0.1);
            }

            .suite-card.success {
                border-left: 4px solid #4caf50;
            }

            .suite-card.failure {
                border-left: 4px solid #f44336;
            }

            .suite-header {
                display: flex;
                justify-content: space-between;
                align-items: center;
                margin-bottom: 10px;
            }

            .suite-header h3 {
                margin: 0;
                color: #333;
            }

            .suite-stats {
                background: #f5f5f5;
                padding: 4px 12px;
                border-radius: 20px;
                font-size: 0.9em;
                color: #666;
            }

            .suite-error {
                background: #ffcdd2;
                color: #c62828;
                padding: 4px 12px;
                border-radius: 20px;
                font-size: 0.9em;
            }

            .error-details {
                background: #fff3e0;
                border: 1px solid #ffb74d;
                border-radius: 4px;
                padding: 10px;
                margin-top: 10px;
                color: #e65100;
                font-size: 0.9em;
            }

            .failed-tests {
                margin-top: 15px;
                padding: 15px;
                background: #ffebee;
                border-radius: 4px;
            }

            .failed-test {
                margin: 5px 0;
                padding: 5px;
                background: white;
                border-radius: 3px;
                font-family: monospace;
                font-size: 0.85em;
                color: #c62828;
            }

            @media (max-width: 768px) {
                .summary-cards {
                    grid-template-columns: 1fr;
                }

                .suite-header {
                    flex-direction: column;
                    align-items: flex-start;
                    gap: 10px;
                }
            }
        `;

        document.head.appendChild(styles);
    }
}

export default TestRunner;