#!/usr/bin/env python3
"""
Probe the AI Agent error + post-click state on talkingwidget.ai.
Extended wait after click to catch async Simli/Telnyx events.
"""

import asyncio
import json
from pathlib import Path
from playwright.async_api import async_playwright

SCREENSHOTS_DIR = Path("/mnt/e/genesis-system/qa_reports")
SCREENSHOTS_DIR.mkdir(exist_ok=True)


async def eval_js(page, js, label=""):
    try:
        return await page.evaluate(js)
    except Exception as e:
        print(f"  [JS ERR {label}] {e}")
        return None


async def run_test():
    console_logs = []
    network_requests = []

    print("\n" + "="*60)
    print("TALKINGWIDGET.AI — ERROR PROBE v3")
    print("="*60)

    async with async_playwright() as p:
        browser = await p.chromium.launch(
            headless=True,
            args=[
                '--no-sandbox',
                '--disable-setuid-sandbox',
                '--disable-dev-shm-usage',
                '--autoplay-policy=no-user-gesture-required',
                '--use-fake-ui-for-media-stream',
                '--use-fake-device-for-media-stream',
            ]
        )

        context = await browser.new_context(
            viewport={'width': 1280, 'height': 900},
            permissions=['microphone', 'camera'],
        )
        page = await context.new_page()

        def on_console(msg):
            entry = {'type': msg.type, 'text': msg.text}
            console_logs.append(entry)
            # Print everything
            print(f"  [CONSOLE/{msg.type.upper()}] {msg.text[:500]}")

        def on_pageerror(err):
            print(f"  [PAGE ERROR] {str(err)[:300]}")

        def on_request(req):
            url = req.url
            if any(kw in url for kw in ['telnyx', 'simli', 'api', 'session', 'token', 'assistant']):
                print(f"  [NET REQUEST] {req.method} {url[:150]}")
                network_requests.append({'method': req.method, 'url': url})

        def on_response(resp):
            url = resp.url
            if any(kw in url for kw in ['telnyx', 'simli', 'api', 'session', 'token', 'assistant']):
                print(f"  [NET RESPONSE] {resp.status} {url[:150]}")

        page.on('console', on_console)
        page.on('pageerror', on_pageerror)
        page.on('request', on_request)
        page.on('response', on_response)

        print("\n[STEP 1] Navigate ...")
        await page.goto('https://talkingwidget.ai', wait_until='domcontentloaded', timeout=30000)
        print(f"  Title: {await page.title()}")

        print("\n[STEP 2] Wait 4s for SDK init ...")
        await asyncio.sleep(4)

        # Get the full HTML structure of the avatar section
        print("\n[PROBE] Getting avatar section HTML ...")
        avatar_html = await eval_js(page,
            "document.getElementById('avatar-stage') ? document.getElementById('avatar-stage').outerHTML.slice(0, 2000) : 'NOT FOUND'",
            "avatar-stage HTML"
        )
        print(f"  Avatar stage HTML:\n{avatar_html}")

        # Get AI voice engine element
        voice_engine_html = await eval_js(page,
            "document.getElementById('ai-voice-engine') ? document.getElementById('ai-voice-engine').outerHTML.slice(0, 500) : 'NOT FOUND'",
            "voice engine HTML"
        )
        print(f"\n  Voice engine HTML: {voice_engine_html}")

        # What does the Telnyx SDK version say?
        sdk_version = await eval_js(page,
            "document.querySelector('[data-version]') ? document.querySelector('[data-version]').getAttribute('data-version') : 'not found'",
            "sdk version"
        )
        print(f"\n  SDK data-version attribute: {sdk_version}")

        # Check if the Telnyx SDK is loaded
        telnyx_sdk = await eval_js(page, "typeof window.TelnyxRTC !== 'undefined'", "TelnyxRTC")
        print(f"  TelnyxRTC loaded: {telnyx_sdk}")

        # List ALL window properties that look relevant
        window_props = await eval_js(page,
            """
            Object.keys(window).filter(k => {
                const kl = k.toLowerCase();
                return kl.includes('simli') || kl.includes('telnyx') || kl.includes('ai') ||
                       kl.includes('avatar') || kl.includes('agent') || kl.includes('bridge') ||
                       kl.includes('voice') || kl.includes('widget');
            })
            """,
            "window props"
        )
        print(f"  All relevant window props: {window_props}")

        # Screenshot before click
        await page.screenshot(path=str(SCREENSHOTS_DIR / "talkingwidget_03_pre_click_zoom.png"), full_page=False)

        print("\n[STEP 5] Clicking overlay ...")
        overlay = await page.query_selector('#avatar-idle-overlay')
        if overlay:
            await overlay.click()
            print("  Clicked #avatar-idle-overlay")

        # Wait 1 second and check intermediate state
        await asyncio.sleep(1)
        print("\n  [1s after click] State check ...")
        avatar_class_1s = await eval_js(page,
            "document.getElementById('avatar-stage')?.className",
            "avatar 1s"
        )
        va_fired_1s = await eval_js(page, "window._vaStartFired", "_vaStartFired 1s")
        bridge_1s = await eval_js(page, "window._simliBridgeState", "_bridge 1s")
        simli_client_1s = await eval_js(page, "!!window._simliClient", "_simliClient 1s")
        print(f"    avatar-stage: {avatar_class_1s}")
        print(f"    _vaStartFired: {va_fired_1s}")
        print(f"    _simliBridgeState: {bridge_1s}")
        print(f"    _simliClient: {simli_client_1s}")

        # Wait another 2 seconds
        await asyncio.sleep(2)
        print("\n  [3s after click] State check ...")
        va_fired_3s = await eval_js(page, "window._vaStartFired", "_vaStartFired 3s")
        bridge_3s = await eval_js(page, "window._simliBridgeState", "_bridge 3s")
        simli_vid_3s = await eval_js(page, "!!document.getElementById('simli-vid')", "simli-vid 3s")
        telnyx_connected = await eval_js(page, "window._telnyxConnected", "_telnyxConnected 3s")
        print(f"    _vaStartFired: {va_fired_3s}")
        print(f"    _simliBridgeState: {bridge_3s}")
        print(f"    simli-vid exists: {simli_vid_3s}")
        print(f"    _telnyxConnected: {telnyx_connected}")

        # Wait more
        await asyncio.sleep(5)
        print("\n  [8s after click] Final state check ...")
        final_avatar = await eval_js(page, "document.getElementById('avatar-stage')?.className", "final avatar")
        final_simli_vid = await eval_js(page, "!!document.getElementById('simli-vid')", "final simli-vid")
        final_bridge = await eval_js(page, "window._simliBridgeState", "final bridge")
        final_va_fired = await eval_js(page, "window._vaStartFired", "final va")
        final_simli_client = await eval_js(page, "!!window._simliClient", "final simliClient")
        print(f"    avatar-stage: {final_avatar}")
        print(f"    simli-vid: {final_simli_vid}")
        print(f"    _simliBridgeState: {final_bridge}")
        print(f"    _vaStartFired: {final_va_fired}")
        print(f"    _simliClient: {final_simli_client}")

        # Screenshot after extended wait
        await page.screenshot(path=str(SCREENSHOTS_DIR / "talkingwidget_04_8s_post_click.png"), full_page=False)

        # Get ALL window Simli properties specifically
        simli_window = await eval_js(page,
            """
            (() => {
                const result = {};
                for (const k of Object.keys(window)) {
                    if (k.toLowerCase().includes('simli')) {
                        const v = window[k];
                        result[k] = typeof v === 'function' ? '[function]' : String(v).slice(0, 100);
                    }
                }
                return result;
            })()
            """,
            "simli window"
        )
        print(f"\n  All window._simli* properties: {simli_window}")

        # Check if voice element changed
        voice_el_state = await eval_js(page,
            """
            (() => {
                const el = document.getElementById('ai-voice-engine');
                if (!el) return 'NOT FOUND';
                return {
                    tagName: el.tagName,
                    className: el.className,
                    attributes: Array.from(el.attributes).map(a => a.name + '=' + a.value),
                    childCount: el.children.length,
                    innerHTML: el.innerHTML.slice(0, 500),
                };
            })()
            """,
            "voice el state"
        )
        print(f"\n  #ai-voice-engine final state: {json.dumps(voice_el_state, indent=2) if voice_el_state else 'N/A'}")

        # Check what's in the avatar-stage now
        avatar_stage_final = await eval_js(page,
            """
            (() => {
                const el = document.getElementById('avatar-stage');
                if (!el) return 'NOT FOUND';
                return el.innerHTML.slice(0, 1000);
            })()
            """,
            "avatar stage final HTML"
        )
        print(f"\n  #avatar-stage final innerHTML:\n{avatar_stage_final}")

        # FULL console log dump
        print("\n" + "="*40)
        print("FULL CONSOLE LOG DUMP:")
        for log in console_logs:
            print(f"  [{log['type'].upper()}] {log['text']}")

        print("\n" + "="*40)
        print("NETWORK REQUESTS TO APIs:")
        for req in network_requests:
            print(f"  {req['method']} {req['url']}")

        await browser.close()

    print("\n" + "="*60)
    print("PROBE COMPLETE")
    print("="*60)


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