import os
import sys
import json
import asyncio
from playwright.async_api import async_playwright

if hasattr(sys.stdout, "reconfigure"):
    sys.stdout.reconfigure(encoding="utf-8")
if hasattr(sys.stderr, "reconfigure"):
    sys.stderr.reconfigure(encoding="utf-8")

async def test_full_media_recorder_capture():
    html_path = os.path.abspath('app/static/bim/index.html').replace('\\', '/')
    file_url = f'file:///{html_path}'
    print(f'=== TESTING REAL MEDIA RECORDER CAPTURE STREAM ===')

    async with async_playwright() as p:
        browser = await p.chromium.launch(
            channel="chrome",
            headless=True,
            args=[
                "--enable-usermedia-screen-capturing",
                "--allow-http-screen-capture",
                "--use-fake-ui-for-media-stream"
            ]
        )
        page = await browser.new_page(viewport={"width": 1920, "height": 1080})
        
        console_errors = []
        page.on('console', lambda msg: console_errors.append(msg.text) if msg.type == 'error' else None)
        page.on('pageerror', lambda exc: console_errors.append(str(exc)))

        await page.goto(file_url, wait_until='load')
        await page.wait_for_timeout(1500)

        recorder_result = await page.evaluate('''() => {
            return new Promise((resolve) => {
                const canvas = document.querySelector('canvas');
                if (!canvas) return resolve({ error: 'No canvas' });

                const stream = canvas.captureStream(30);
                let mimeType = 'video/webm;codecs=vp9';
                if (!MediaRecorder.isTypeSupported(mimeType)) {
                    mimeType = 'video/webm';
                }

                const recorder = new MediaRecorder(stream, { mimeType: mimeType });
                const recordedChunks = [];
                let frameDrawCount = 0;

                recorder.ondataavailable = (e) => {
                    if (e.data && e.data.size > 0) {
                        recordedChunks.push(e.data);
                    }
                };

                recorder.onstop = () => {
                    const blob = new Blob(recordedChunks, { type: mimeType });
                    resolve({
                        success: true,
                        mimeType: mimeType,
                        blobSize: blob.size,
                        chunksCount: recordedChunks.length,
                        framesDrawn: frameDrawCount,
                        spritesRendered: window.groupDimensions ? window.groupDimensions.children.filter(c => c.isSprite).length : 0
                    });
                };

                recorder.start(100);

                // Render loop for 1.2 seconds (approx 36 frames)
                const startTime = performance.now();
                function renderLoop() {
                    renderer.render(scene, camera);
                    frameDrawCount++;
                    if (performance.now() - startTime < 1200) {
                        requestAnimationFrame(renderLoop);
                    } else {
                        recorder.stop();
                    }
                }
                requestAnimationFrame(renderLoop);
            });
        }''')

        await browser.close()
        print('MediaRecorder Test Result:', json.dumps(recorder_result, indent=2))
        assert recorder_result.get('success') is True, f"Recorder failed: {recorder_result}"
        assert recorder_result.get('blobSize') > 10000, f"Recorded blob too small: {recorder_result.get('blobSize')} bytes"
        assert recorder_result.get('spritesRendered') == 21, f"Expected 21 sprites rendered: {recorder_result.get('spritesRendered')}"
        print(f"Recorded valid video stream: {recorder_result.get('blobSize')} bytes with all 21 sprites rendered into WebGL framebuffer.")
        return recorder_result

if __name__ == '__main__':
    asyncio.run(test_full_media_recorder_capture())
