#!/usr/bin/env python3
"""
Deep diagnostic for talkingwidget.ai — fixed JS evaluation + extended state capture.
"""

import asyncio
import json
import time
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="JS"):
    """Safe JS evaluator."""
    try:
        result = await page.evaluate(js)
        return result
    except Exception as e:
        print(f"  [JS ERROR - {label}] {e}")
        return None


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

    print("\n" + "="*60)
    print("TALKINGWIDGET.AI — DEEP DIAGNOSTIC v2")
    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',
                '--disable-web-security',
            ]
        )

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

        page = await context.new_page()

        # Capture console
        def on_console(msg):
            text = msg.text
            entry = {'type': msg.type, 'text': text}
            console_logs.append(entry)
            # Print anything voice/simli/telnyx related immediately
            if any(kw in text.lower() for kw in ['simli', 'telnyx', 'voice', 'avatar', 'agent', 'session', 'stream', 'error', 'bridge', 'token']):
                print(f"  [CONSOLE/{msg.type.upper()}] {text[:400]}")

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

        def on_requestfailed(req):
            print(f"  [NET FAIL] {req.method} {req.url[:100]}")
            network_errors.append(req.url)

        page.on('console', on_console)
        page.on('pageerror', on_pageerror)
        page.on('requestfailed', on_requestfailed)

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

        # STEP 2: Wait 4 seconds
        print("\n[STEP 2] Waiting 4 seconds ...")
        await asyncio.sleep(4)

        # STEP 3: Screenshot
        print("\n[STEP 3] Screenshot 1 (initial) ...")
        await page.screenshot(path=str(SCREENSHOTS_DIR / "talkingwidget_01_initial.png"), full_page=True)
        print(f"  Saved: qa_reports/talkingwidget_01_initial.png")

        # STEP 4: Initial state checks
        print("\n[STEP 4] Initial state checks ...")

        # Check avatar-stage
        avatar_stage_class = await eval_js(page,
            "document.getElementById('avatar-stage') ? document.getElementById('avatar-stage').className : 'NOT FOUND'",
            "avatar-stage class"
        )
        print(f"  #avatar-stage.className: {avatar_stage_class}")

        # Check simli-vid
        simli_vid_exists = await eval_js(page,
            "!!document.getElementById('simli-vid')",
            "simli-vid exists"
        )
        simli_vid_display = await eval_js(page,
            "document.getElementById('simli-vid') ? document.getElementById('simli-vid').style.display : 'N/A'",
            "simli-vid display"
        )
        print(f"  #simli-vid exists: {simli_vid_exists}")
        print(f"  #simli-vid display: {simli_vid_display}")

        # Check ai-voice-engine
        voice_el_exists = await eval_js(page, "!!document.getElementById('ai-voice-engine')", "voice-el")
        voice_agent_id = await eval_js(page,
            "document.getElementById('ai-voice-engine') ? document.getElementById('ai-voice-engine').getAttribute('agent-id') : 'N/A'",
            "agent-id"
        )
        print(f"  #ai-voice-engine exists: {voice_el_exists}")
        print(f"  agent-id: {voice_agent_id}")

        # Check avatar-idle-overlay
        overlay_exists = await eval_js(page, "!!document.getElementById('avatar-idle-overlay')", "overlay")
        print(f"  #avatar-idle-overlay exists: {overlay_exists}")

        # Check window Simli state
        simli_loaded = await eval_js(page, "typeof window.SimliClient !== 'undefined'", "SimliClient")
        simli_client = await eval_js(page, "!!window._simliClient", "_simliClient")
        session_token = await eval_js(page, "!!window._simliSessionToken", "_simliSessionToken")
        bridge_state = await eval_js(page, "window._simliBridgeState || 'not-set'", "bridgeState")
        va_start_fired = await eval_js(page, "window._vaStartFired || false", "_vaStartFired")
        print(f"  SimliClient loaded: {simli_loaded}")
        print(f"  _simliClient exists: {simli_client}")
        print(f"  _simliSessionToken: {session_token}")
        print(f"  _simliBridgeState: {bridge_state}")
        print(f"  _vaStartFired: {va_start_fired}")

        # List all window keys with simli/telnyx
        window_keys = await eval_js(page,
            "Object.keys(window).filter(k => k.toLowerCase().includes('simli') || k.toLowerCase().includes('telnyx') || k.toLowerCase().includes('va') || k.toLowerCase().includes('bridge'))",
            "window keys"
        )
        print(f"  Relevant window keys: {window_keys}")

        # STEP 5: Click the overlay
        print("\n[STEP 5] Clicking #avatar-idle-overlay ...")
        overlay = await page.query_selector('#avatar-idle-overlay')
        if overlay:
            visible = await overlay.is_visible()
            print(f"  Overlay visible: {visible}")
            await overlay.click()
            print(f"  Clicked.")
        else:
            print("  OVERLAY NOT FOUND — falling back to coordinate click")
            await page.mouse.click(640, 400)

        # STEP 6: Wait 5 seconds
        print("\n[STEP 6] Waiting 5 seconds post-click ...")
        await asyncio.sleep(5)

        # STEP 7: Post-click screenshot
        print("\n[STEP 7] Screenshot 2 (post-click) ...")
        await page.screenshot(path=str(SCREENSHOTS_DIR / "talkingwidget_02_post_click.png"), full_page=True)
        print(f"  Saved: qa_reports/talkingwidget_02_post_click.png")

        # STEP 8: Post-click state
        print("\n[STEP 8] Post-click state ...")

        avatar_stage_class_2 = await eval_js(page,
            "document.getElementById('avatar-stage') ? document.getElementById('avatar-stage').className : 'NOT FOUND'",
            "avatar-stage post-click"
        )
        in_call = await eval_js(page,
            "document.getElementById('avatar-stage') ? document.getElementById('avatar-stage').classList.contains('in-call') : false",
            "in-call"
        )
        va_start_2 = await eval_js(page, "window._vaStartFired || false", "_vaStartFired post")
        bridge_state_2 = await eval_js(page, "window._simliBridgeState || 'not-set'", "bridgeState post")
        simli_client_2 = await eval_js(page, "!!window._simliClient", "_simliClient post")

        print(f"  #avatar-stage.className: {avatar_stage_class_2}")
        print(f"  in-call class present: {in_call}")
        print(f"  _vaStartFired: {va_start_2}")
        print(f"  _simliBridgeState: {bridge_state_2}")
        print(f"  _simliClient exists: {simli_client_2}")

        # STEP 9: Video element check
        print("\n[STEP 9] Simli video element check ...")
        simli_vid_exists_2 = await eval_js(page, "!!document.getElementById('simli-vid')", "simli-vid post")
        print(f"  #simli-vid exists: {simli_vid_exists_2}")

        if simli_vid_exists_2:
            vid_display = await eval_js(page,
                "document.getElementById('simli-vid').style.display",
                "vid display"
            )
            vid_computed_display = await eval_js(page,
                "getComputedStyle(document.getElementById('simli-vid')).display",
                "vid computed display"
            )
            vid_ready_state = await eval_js(page,
                "document.getElementById('simli-vid').readyState",
                "vid readyState"
            )
            vid_src_object = await eval_js(page,
                "!!document.getElementById('simli-vid').srcObject",
                "vid srcObject"
            )
            vid_video_width = await eval_js(page,
                "document.getElementById('simli-vid').videoWidth",
                "vid videoWidth"
            )
            vid_paused = await eval_js(page,
                "document.getElementById('simli-vid').paused",
                "vid paused"
            )
            rect = await eval_js(page,
                "JSON.stringify(document.getElementById('simli-vid').getBoundingClientRect())",
                "vid rect"
            )
            print(f"  display (style): {vid_display}")
            print(f"  display (computed): {vid_computed_display}")
            print(f"  readyState: {vid_ready_state}")
            print(f"  srcObject: {vid_src_object}")
            print(f"  videoWidth: {vid_video_width}")
            print(f"  paused: {vid_paused}")
            if rect:
                rect_obj = json.loads(rect) if isinstance(rect, str) else rect
                print(f"  rect: {rect_obj}")
        else:
            print("  #simli-vid does NOT exist after click — avatar video never injected")

        # STEP 10: Console log analysis
        print("\n[STEP 10] Console log summary ...")
        simli_success_keywords = [
            'avatar stream live',
            'session connected',
            'lip sync',
            'stream live',
            'webrtc',
            'ice connected',
            'data channel',
        ]
        telnyx_error_keywords = ['telnyx', 'error', 'failed']

        print("\n  ALL console logs captured:")
        for log in console_logs:
            print(f"    [{log['type'].upper()}] {log['text'][:300]}")

        print("\n  Simli success markers found:")
        found_any = False
        for log in console_logs:
            for kw in simli_success_keywords:
                if kw in log['text'].lower():
                    print(f"    ✓ {log['text'][:200]}")
                    found_any = True
                    break
        if not found_any:
            print("    NONE — No Simli success markers found")

        print("\n  Network failures:")
        if network_errors:
            for url in network_errors:
                print(f"    FAIL: {url}")
        else:
            print("    None")

        # Extra: check what the ai-agent-widget error was
        print("\n  Detailed error analysis ...")
        error_logs = [l for l in console_logs if l['type'] == 'error']
        if error_logs:
            print(f"  Total errors: {len(error_logs)}")
            for el in error_logs:
                print(f"    [ERROR] {el['text'][:400]}")
        else:
            print("  No console errors logged")

        # Check for any Telnyx error shown in DOM
        error_dom = await eval_js(page,
            """
            (() => {
                const all = document.querySelectorAll('[class*="error"], [id*="error"], [class*="warning"]');
                const texts = [];
                all.forEach(el => { if (el.innerText.trim()) texts.push(el.innerText.trim().slice(0, 100)); });
                return texts.join(' | ');
            })()
            """,
            "DOM errors"
        )
        print(f"\n  DOM error elements text: {error_dom or 'None'}")

        # Page full text snapshot
        page_text = await eval_js(page, "document.body.innerText.slice(0, 2000)", "page text")
        print(f"\n  Page text (first 2000 chars):\n{page_text}")

        await browser.close()

    print("\n" + "="*60)
    print("DIAGNOSTIC COMPLETE")
    print("Screenshots in: /mnt/e/genesis-system/qa_reports/")
    print("="*60)


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