#!/usr/bin/env python3
"""
Diagnostic #5 — Check SimliClient version, what it throws, and headless video issue
"""
import asyncio
import json
from playwright.async_api import async_playwright

async def run():
    async with async_playwright() as p:
        browser = await p.chromium.launch(
            headless=True,
            args=[
                "--use-fake-ui-for-media-stream",
                "--use-fake-device-for-media-stream",
                "--autoplay-policy=no-user-gesture-required",
                "--no-sandbox",
                "--enable-features=WebRTC",
            ]
        )
        context = await browser.new_context(permissions=["microphone"])
        await context.grant_permissions(["microphone"], origin="https://talkingwidget.ai")

        console_messages = []
        page = await context.new_page()
        page.on("console", lambda msg: console_messages.append(f"[{msg.type.upper()}] {msg.text}"))

        print("[D5] Navigating...")
        await page.goto("https://talkingwidget.ai", wait_until="networkidle", timeout=45000)
        await asyncio.sleep(3)

        # Click to trigger call
        print("[D5] Clicking overlay...")
        await page.click('#avatar-idle-overlay')
        await asyncio.sleep(5)  # Wait for WebRTC to be fully connected

        # Now test SimliClient carefully step by step
        simli_detailed = await page.evaluate("""async () => {
            var results = {};

            // Step 1: Import
            try {
                const mod = await import('https://esm.sh/simli-client@3');
                results.exports = Object.keys(mod);
                results.SimliClientType = typeof mod.SimliClient;
                var SimliClient = mod.SimliClient;

                // Step 2: Get token
                const resp = await fetch('https://api.sunaivadigital.com/api/simli/session-token', {
                    method: 'POST',
                    headers: {'Content-Type': 'application/json'},
                    body: JSON.stringify({faceId: 'd2a5c7c6-fed9-4f55-bcb3-062f7cd20103', model: 'artalk', handleSilence: false, maxSessionLength: 600, maxIdleTime: 90})
                });
                const data = await resp.json();
                results.tokenStatus = resp.status;
                results.tokenOk = !!data.session_token;
                results.tokenLen = data.session_token ? data.session_token.length : 0;

                // Step 3: Create elements
                var frame = document.querySelector('.avatar-frame') || document.getElementById('avatar-vid')?.parentElement;
                results.frameFound = !!frame;

                var vid = document.createElement('video');
                vid.id = 'simli-test-vid';
                vid.autoplay = true;
                vid.playsInline = true;
                vid.muted = true;
                var aud = document.createElement('audio');
                aud.id = 'simli-test-aud';
                aud.autoplay = true;
                if (frame) { frame.appendChild(vid); frame.appendChild(aud); }

                // Step 4: Instantiate client
                const client = new SimliClient();
                results.clientCreated = true;
                results.clientMethods = Object.getOwnPropertyNames(Object.getPrototypeOf(client)).filter(m => typeof client[m] === 'function');

                // Step 5: Initialize
                try {
                    await client.Initialize({
                        apiKey: data.session_token,
                        faceID: 'd2a5c7c6-fed9-4f55-bcb3-062f7cd20103',
                        handleSilence: false,
                        videoRef: vid,
                        audioRef: aud,
                        startVideoFirst: false,
                        maxSessionLength: 600,
                        maxIdleTime: 90,
                    });
                    results.initializeOk = true;
                    console.log('[D5] Initialize succeeded');
                } catch (initErr) {
                    results.initializeError = {
                        message: initErr?.message,
                        name: initErr?.name,
                        type: Object.prototype.toString.call(initErr),
                        stringified: JSON.stringify(initErr),
                        isUndefined: initErr === undefined
                    };
                    console.log('[D5] Initialize error:', JSON.stringify(results.initializeError));
                    return results;
                }

                // Step 6: Attach event handlers BEFORE start
                client.on('connected', function() { console.log('[D5] Simli CONNECTED!'); });
                client.on('disconnected', function() { console.log('[D5] Simli disconnected'); });
                client.on('failed', function() { console.log('[D5] Simli FAILED'); });
                client.on('error', function(e) { console.log('[D5] Simli error event:', e); });

                // Step 7: Start
                var startResult;
                try {
                    startResult = await client.start();
                    results.startOk = true;
                    results.startResult = typeof startResult;
                    console.log('[D5] start() succeeded, result:', typeof startResult);
                } catch (startErr) {
                    results.startError = {
                        message: startErr?.message,
                        name: startErr?.name,
                        type: Object.prototype.toString.call(startErr),
                        isUndefined: startErr === undefined,
                        isNull: startErr === null,
                        stringified: String(startErr),
                        fullJSON: (() => { try { return JSON.stringify(startErr); } catch(e) { return 'circular'; } })()
                    };
                    // If startErr itself is undefined, the promise rejected with undefined
                    if (startErr === undefined) {
                        results.startError.interpretation = 'Promise rejected with undefined — likely a non-Error rejection from SimliClient internals';
                    }
                    console.log('[D5] start() error type:', results.startError.type);
                    console.log('[D5] start() error:', results.startError.stringified);
                }

            } catch (e) {
                results.outerError = {message: e?.message, name: e?.name, stack: e?.stack?.slice(0, 400)};
            }

            return results;
        }""")
        print(f"[D5] SimliClient detailed test:")
        print(json.dumps(simli_detailed, indent=2))

        # Also check: is headless causing video/WebRTC issues for Simli?
        # Simli uses WebRTC internally to receive the video stream
        webrtc_check = await page.evaluate("""() => {
            return {
                RTCPeerConnectionExists: typeof RTCPeerConnection !== 'undefined',
                RTCDataChannelExists: typeof RTCDataChannel !== 'undefined',
                getUserMediaExists: !!(navigator.mediaDevices && navigator.mediaDevices.getUserMedia),
                WebSocketExists: typeof WebSocket !== 'undefined',
                // Check if simli-vid was mounted
                simliVidExists: !!document.getElementById('simli-vid'),
                simliVidDisplay: document.getElementById('simli-vid')?.style?.display || 'N/A',
                simliTestVidExists: !!document.getElementById('simli-test-vid'),
                simliTestAudExists: !!document.getElementById('simli-test-aud'),
                // Avatar stage class (should be 'in-call' after click)
                avatarStageClass: document.getElementById('avatar-stage')?.className || 'N/A'
            };
        }""")
        print(f"\n[D5] WebRTC/DOM capabilities: {json.dumps(webrtc_check, indent=2)}")

        print("\n[D5] Console messages:")
        for msg in console_messages:
            print(f"  {msg}")

        await browser.close()

if __name__ == "__main__":
    asyncio.run(run())
