#!/usr/bin/env node

/**
 * Critical Test: Content Rendering Validation
 *
 * This test ensures that content actually renders despite any JavaScript enhancements.
 * It catches JavaScript syntax errors that would prevent basic content display.
 */

const { TestRunner, HTMLFileTester } = require('./test_runner.js');
const fs = require('fs');

const runner = new TestRunner();

runner.describe('Critical Content Rendering Validation', () => {

    let htmlTester;
    const testHtmlPath = '/tmp/test_content_rendering.html';

    runner.it('should generate valid HTML that renders content without JavaScript errors', async () => {
        // Create simple test content
        const testMarkdown = `# Test Content Rendering

This is critical test content that MUST render even if JavaScript fails.

## Basic Content
- List item 1
- List item 2

\`\`\`javascript
console.log("test");
\`\`\`

> Quote content that should be visible

Final paragraph content.`;

        // Write test markdown
        fs.writeFileSync('/tmp/test_content_source.md', testMarkdown);

        // Generate HTML using markitect
        const { execSync } = require('child_process');
        try {
            execSync(`cd /home/worsch/markitect_project && MARKITECT_EDIT_MODE=true markitect md-render /tmp/test_content_source.md --output ${testHtmlPath}`,
                    { stdio: 'pipe' });
            runner.expect(fs.existsSync(testHtmlPath)).toBeTruthy();
        } catch (error) {
            throw new Error(`Failed to generate HTML: ${error.message}`);
        }
    });

    runner.it('should have basic HTML structure with content', async () => {
        htmlTester = new HTMLFileTester(testHtmlPath);
        const loaded = await htmlTester.load();

        runner.expect(loaded || htmlTester.html).toBeTruthy();
        runner.expect(htmlTester.html.length).toBeGreaterThan(1000); // Should have substantial content
    });

    runner.it('should have markdown content available for JavaScript rendering', async () => {
        // Check that the markdown content is embedded in JavaScript for dynamic rendering
        runner.expect(htmlTester.html.includes('Test Content Rendering')).toBeTruthy(); // Title in JS string
        runner.expect(htmlTester.html.includes('Basic Content')).toBeTruthy(); // Subheading in JS string
        runner.expect(htmlTester.html.includes('List item 1')).toBeTruthy(); // List content in JS string
        runner.expect(htmlTester.html.includes('Final paragraph')).toBeTruthy(); // Final content in JS string

        // Check that JavaScript rendering templates are present
        runner.expect(htmlTester.html.includes('.replace(/^# (.*$)/gim, \'<h1>$1</h1>\')')).toBeTruthy(); // H1 rendering
        runner.expect(htmlTester.html.includes('.replace(/^## (.*$)/gim, \'<h2>$1</h2>\')')).toBeTruthy(); // H2 rendering
        runner.expect(htmlTester.html.includes('markdownContent')).toBeTruthy(); // Content variable exists

        // Check for target container
        runner.expect(htmlTester.html.includes('id="markdown-content"')).toBeTruthy(); // Target container exists
    });

    runner.it('should not have JavaScript syntax errors that prevent execution', async () => {
        // Check for common JavaScript syntax issues in the HTML
        const jsContent = htmlTester.html;

        // Check for unclosed strings
        const unclosedStrings = jsContent.match(/['"`][^'"`\n]*[\n]/g);
        if (unclosedStrings) {
            console.warn('Potential unclosed strings found:', unclosedStrings.slice(0, 3));
        }

        // Check for mismatched brackets
        const openBrackets = (jsContent.match(/[({[]/g) || []).length;
        const closeBrackets = (jsContent.match(/[)}\]]/g) || []).length;

        // Allow some tolerance for string content
        const bracketDiff = Math.abs(openBrackets - closeBrackets);
        runner.expect(bracketDiff).toBeLessThan(10); // Should be reasonably balanced

        // Check for obvious syntax errors - these are valid syntax patterns
        // Note: 'function (' with space is valid JavaScript syntax
        const hasFunctionSyntax = jsContent.includes('function(') || jsContent.includes('function (');
        runner.expect(hasFunctionSyntax).toBeTruthy(); // Should have functions

        const hasProperBraces = jsContent.includes(') {') || jsContent.includes('){');
        runner.expect(hasProperBraces).toBeTruthy(); // Should have proper function/if syntax
    });

    runner.it('should have fallback mechanisms for JavaScript failures', async () => {
        // Test that there are graceful degradation mechanisms in place
        const markdownContainer = htmlTester.html.match(/<div[^>]*id=["']markdown-content["'][^>]*>([\s\S]*?)<\/div>/i);

        runner.expect(markdownContainer).toBeTruthy();

        // The container should exist even if initially empty (content is added by JS)
        const hasContainer = htmlTester.html.includes('id="markdown-content"');
        runner.expect(hasContainer).toBeTruthy();

        // Should have noscript alternative or error handling
        const hasGracefulDegradation = htmlTester.html.includes('noscript') ||
                                     htmlTester.html.includes('try {') ||
                                     htmlTester.html.includes('catch');
        runner.expect(hasGracefulDegradation).toBeTruthy();
    });

    runner.it('should have fallback content rendering strategy', async () => {
        // Check for graceful degradation comments or fallback mechanisms
        const hasFallback = htmlTester.html.includes('graceful') ||
                           htmlTester.html.includes('fallback') ||
                           htmlTester.html.includes('degradation') ||
                           htmlTester.html.includes('<!-- Content rendered');

        runner.expect(hasFallback).toBeTruthy();
    });

    runner.it('should initialize JavaScript without blocking content display', async () => {
        if (htmlTester.window && htmlTester.document) {
            // Test that JavaScript can initialize without errors
            let jsErrors = [];
            const originalConsoleError = htmlTester.window.console.error;
            htmlTester.window.console.error = (...args) => {
                jsErrors.push(args.join(' '));
                originalConsoleError.apply(htmlTester.window.console, args);
            };

            try {
                // Wait a bit for JavaScript to initialize
                await new Promise(resolve => setTimeout(resolve, 1000));

                // Check if there were critical JavaScript errors
                const criticalErrors = jsErrors.filter(error =>
                    error.includes('SyntaxError') ||
                    error.includes('ReferenceError') ||
                    error.includes('TypeError') && error.includes('undefined')
                );

                if (criticalErrors.length > 0) {
                    console.warn('JavaScript errors detected:', criticalErrors);
                }

                // Should not have syntax errors that prevent basic execution
                const syntaxErrors = jsErrors.filter(error => error.includes('SyntaxError'));
                runner.expect(syntaxErrors.length).toBe(0);

            } finally {
                htmlTester.window.console.error = originalConsoleError;
            }
        } else {
            // Fallback: just check that HTML structure is sound
            runner.expect(htmlTester.html.includes('</html>')).toBeTruthy();
        }
    });

    runner.it('should have content prepared for rendering without blocking', async () => {
        // Check that content is ready for rendering (in JS variables)
        runner.expect(htmlTester.html.includes('markdownContent')).toBeTruthy();
        runner.expect(htmlTester.html.includes('Test Content Rendering')).toBeTruthy();

        // Check that rendering doesn't block page load
        const hasAsyncLoading = htmlTester.html.includes('DOMContentLoaded') ||
                               htmlTester.html.includes('defer') ||
                               htmlTester.html.includes('async');
        runner.expect(hasAsyncLoading).toBeTruthy();

        // Container should be immediately available
        runner.expect(htmlTester.html.includes('id="markdown-content"')).toBeTruthy();
    });

    runner.it('should have proper error handling for JavaScript failures', async () => {
        // Check for try-catch blocks and error handling
        const hasErrorHandling = htmlTester.html.includes('try {') &&
                                 htmlTester.html.includes('catch') &&
                                 htmlTester.html.includes('console.error');

        runner.expect(hasErrorHandling).toBeTruthy();

        // Check for fallback initialization
        const hasFallbackInit = htmlTester.html.includes('window.addEventListener') ||
                               htmlTester.html.includes('DOMContentLoaded') ||
                               htmlTester.html.includes('document.ready');

        runner.expect(hasFallbackInit).toBeTruthy();
    });
});

// Cleanup
runner.describe('Test Cleanup', () => {
    runner.it('should clean up test files', async () => {
        const filesToClean = [
            '/tmp/test_content_source.md',
            '/tmp/test_content_rendering.html'
        ];

        filesToClean.forEach(file => {
            if (fs.existsSync(file)) {
                fs.unlinkSync(file);
            }
        });

        runner.expect(true).toBeTruthy();
    });
});

// Run the tests
if (require.main === module) {
    console.log('🚨 Running CRITICAL Content Rendering Validation Tests');
    console.log('This test ensures content renders even with JavaScript issues');
    console.log('');

    runner.run().then(() => {
        const results = runner.results;
        const failed = results.filter(r => r.status === 'FAIL').length;

        if (failed > 0) {
            console.log('');
            console.log('🚨 CRITICAL ISSUE DETECTED:');
            console.log('Content rendering may be broken due to JavaScript problems.');
            console.log('This must be fixed immediately for production use.');
        } else {
            console.log('✅ Content rendering validation passed!');
        }
    });
}

module.exports = runner;