"""
Full Surebet247 API discovery via Playwright WS capture with msgpack decoding.

Captures and decodes all binary WS messages from direct-feed, then prints
the structure of sports, events, and market data.
"""
import json
import asyncio
import msgpack
from playwright.async_api import async_playwright

CONTEXT = ['en', 'MOBILE_WEB', 'CL38B1', '', 'NGN']


def try_decode(data):
    """Try msgpack decode with various length prefix sizes."""
    if isinstance(data, str):
        return None
    for skip in (1, 2, 3, 0):
        try:
            return msgpack.unpackb(data[skip:], raw=False, strict_map_key=False)
        except Exception:
            pass
    return None


async def main():
    captured_frames = []

    async with async_playwright() as p:
        browser = await p.chromium.launch(
            headless=True,
            args=['--no-sandbox', '--disable-blink-features=AutomationControlled'],
        )
        ctx = await browser.new_context(
            user_agent='Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
            viewport={'width': 1280, 'height': 900},
        )
        page = await ctx.new_page()
        ws_conn = [None]

        def on_websocket(ws):
            url = ws.url
            if 'direct-feed' not in url:
                return
            ws_conn[0] = ws
            print(f'[WS OPEN] {url[:100]}')

            def on_sent(payload):
                if isinstance(payload, bytes):
                    decoded = try_decode(payload)
                    if decoded:
                        print(f'  [SENT decoded] {str(decoded)[:200]}')
                    else:
                        print(f'  [SENT bytes] {payload[:30].hex()}')
                else:
                    print(f'  [SENT text] {str(payload)[:200]}')
                captured_frames.append(('sent', payload))

            def on_recv(payload):
                if isinstance(payload, bytes):
                    decoded = try_decode(payload)
                    if decoded:
                        print(f'  [RECV decoded] {str(decoded)[:300]}')
                    else:
                        print(f'  [RECV bytes] {payload[:30].hex()} (len={len(payload)})')
                else:
                    print(f'  [RECV text] {str(payload)[:200]}')
                captured_frames.append(('recv', payload))

            ws.on('framesent', on_sent)
            ws.on('framereceived', on_recv)

        page.on('websocket', on_websocket)

        print('→ Loading football page...')
        await page.goto('https://www.surebet247.com/sport/football',
                        wait_until='domcontentloaded', timeout=30000)

        # Wait for WS to open and data to start flowing
        for _ in range(30):
            await asyncio.sleep(1)
            if ws_conn[0] and len(captured_frames) >= 10:
                break

        # Scroll to trigger more events
        for _ in range(5):
            await page.mouse.wheel(0, 800)
            await asyncio.sleep(0.5)

        await asyncio.sleep(5)
        await browser.close()

    print(f'\n=== SUMMARY: {len(captured_frames)} frames captured ===\n')

    # Decode all frames
    events_found = {}
    markets_found = {}

    for direction, payload in captured_frames:
        if isinstance(payload, bytes):
            decoded = try_decode(payload)
            if not decoded or not isinstance(decoded, (list, tuple)):
                continue

            msg_type = decoded[0] if decoded else None
            rid = decoded[2] if len(decoded) > 2 else None
            data = decoded[4] if len(decoded) > 4 else (decoded[3] if len(decoded) > 3 else None)

            if msg_type == 4 and direction == 'sent':
                method = decoded[3] if len(decoded) > 3 else '?'
                print(f'[RPC sent] id={rid} method={method}')
                print(f'  args: {str(decoded[4])[:200]}')

            elif msg_type == 2 and direction == 'recv':
                print(f'\n[RPC reply] id={rid}')
                if isinstance(data, list):
                    print(f'  → {len(data)} items')
                    # Sample first item
                    if data:
                        first = data[0]
                        print(f'  → first item type: {type(first).__name__}')
                        print(f'  → first item: {str(first)[:400]}')
                    # Check if it looks like events (list of lists with int first element)
                    if data and isinstance(data[0], (list, tuple)) and data[0] and isinstance(data[0][0], int):
                        print(f'  → Looks like EVENTS data')
                        for item in data[:3]:
                            print(f'    event: {str(item)[:300]}')
                            events_found[str(item[0])] = item
                    # Check if it looks like markets
                    elif data and isinstance(data[0], dict):
                        print(f'  → Looks like DICT data (markets?)')
                        print(f'  → Keys: {list(data[0].keys())[:10]}')
                elif isinstance(data, dict):
                    print(f'  → Dict keys: {list(data.keys())[:10]}')
                    print(f'  → {str(data)[:400]}')
                else:
                    print(f'  → {str(data)[:400]}')

    print(f'\nTotal events decoded: {len(events_found)}')
    print(f'Total markets decoded: {len(markets_found)}')

    if events_found:
        print('\n=== SAMPLE EVENT ===')
        eid, ev = next(iter(events_found.items()))
        print(f'Event ID: {eid}')
        print(json.dumps(ev, default=str, ensure_ascii=False, indent=2)[:2000])


asyncio.run(main())
