"""
Test direct WebSocket connection to Surebet247's feed API.
Protocol: Length-prefixed MessagePack RPC frames.

Frame format (observed from Playwright intercept):
  [1 byte length prefix][msgpack array: [4, {}, msg_id_str, method_name, args]]

Response:
  [2 byte length prefix][msgpack array: [2, {}, msg_id_str, [ok_bool, result]]]
"""
import asyncio
import struct
import msgpack
import websockets
import json

WS_URL = 'wss://sport-iframe.serhjs.xyz/direct-feed/feed?brand=CL38B1&X-Api-Key=b8b92942-ce6a-44e8-a5d5-6bf407e316a2'

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

def make_request(msg_id: str, method: str, args: list) -> bytes:
    """Build a MessagePack request frame."""
    payload = msgpack.packb([4, {}, msg_id, method, args], use_bin_type=True)
    # Length prefix: single byte if < 128, else varint-style
    length = len(payload)
    if length < 0x80:
        prefix = bytes([length])
    elif length < 0x4000:
        prefix = bytes([(length >> 8) | 0x80, length & 0xFF])
    else:
        prefix = struct.pack('>I', length)
    return prefix + payload


def decode_response(data: bytes):
    """Decode a length-prefixed MessagePack response."""
    # Try to find the msgpack boundary by skipping length prefix bytes
    for skip in range(1, 4):
        try:
            return msgpack.unpackb(data[skip:], raw=False)
        except Exception:
            pass
    return None


async def main():
    headers = {
        'Origin': 'https://sport-iframe.serhjs.xyz',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
    }

    print(f'Connecting to {WS_URL}...')
    async with websockets.connect(WS_URL, extra_headers=headers, max_size=10_000_000) as ws:
        # Protocol negotiation
        await ws.send(json.dumps({'protocol': 'messagepack', 'version': 1}))
        resp = await ws.recv()
        print(f'Negotiation response: {resp!r}')

        # Request sports list
        req = make_request('0', 'GetSportsByStage', [3, CONTEXT])
        print(f'\nSending GetSportsByStage...')
        await ws.send(req)

        # Request football events (time range 0-24h)
        req2 = make_request('1', 'GetEventsBySportAndTimeRange', ['F', [0, 24], CONTEXT])
        print(f'Sending GetEventsBySportAndTimeRange(F, 0-24h)...')
        await ws.send(req2)

        # Collect responses
        results = {}
        for _ in range(10):
            try:
                data = await asyncio.wait_for(ws.recv(), timeout=5.0)
                if isinstance(data, bytes):
                    decoded = decode_response(data)
                    if decoded and isinstance(decoded, list) and len(decoded) >= 4:
                        msg_id = decoded[2]
                        payload = decoded[3]
                        results[msg_id] = payload
                        print(f'\n[RECV id={msg_id}] type={type(payload).__name__}')
                        if isinstance(payload, list) and len(payload) >= 2:
                            ok = payload[0]
                            result = payload[1]
                            print(f'  ok={ok}, result type={type(result).__name__}')
                            if isinstance(result, list):
                                print(f'  result length={len(result)}')
                                if result:
                                    print(f'  first item: {json.dumps(result[0], default=str)[:500]}')
                    else:
                        print(f'  raw binary: {data[:100]!r}')
                else:
                    print(f'[TEXT] {data[:200]}')
            except asyncio.TimeoutError:
                break

        print('\n\nFull results summary:')
        for mid, v in results.items():
            print(f'  id={mid}: {str(v)[:300]}')


asyncio.run(main())
