"""
Connect directly to the Surebet247 WS and probe different profile names.

The WS URL only requires brand + API key — no browser cookies needed.
We first scrape a few event IDs via the existing scraper, then open a
raw WS connection and try each profile.

Usage:
    python3 tools/discover_surebet247_dc2.py
"""
import sys, os
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))

import time, threading, collections
import msgpack
import websocket
from scrapers.surebet247 import _Surebet247Worker, _decode_frame, _parse_events_from_frames

BASE_SITE = 'https://www.surebet247.com'
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']

PROFILES_TO_TRY = [
    'pro_main_period',
    'pro_all',
    'pro_dc',
    'pro_combo',
    'pro_extended',
    'pro_popular',
    'pro_default',
    'pro_full',
    'pro_main',
    'pro_1x2_dc',
]


def encode_rpc(req_id: int, method: str, args: list) -> bytes:
    payload = [4, {}, req_id, method, args]
    raw = msgpack.packb(payload, use_bin_type=True)
    return b'\x00' + raw


def decode_market_types(data: bytes):
    decoded = _decode_frame(data)
    if not decoded or not isinstance(decoded, (list, tuple)) or decoded[0] != 2:
        return None, []
    reply_data = decoded[3]
    if not isinstance(reply_data, (list, tuple)) or len(reply_data) < 2 or not reply_data[0]:
        return decoded[2], []

    req_id = decoded[2]
    items  = reply_data[1]
    if not isinstance(items, (list, tuple)):
        return req_id, []

    result = {}
    for item in items:
        if not isinstance(item, (list, tuple)) or len(item) < 3:
            continue
        item_key = item[1]
        if not isinstance(item_key, (list, tuple)) or len(item_key) < 3:
            continue
        mtype      = item_key[2]
        market_val = item[2]
        if not isinstance(market_val, (list, tuple)) or not market_val:
            continue
        sgs = market_val[0]
        if not isinstance(sgs, (list, tuple)):
            continue
        for g in sgs:
            if not isinstance(g, (list, tuple)) or len(g) < 2:
                continue
            oc_types = []
            prices   = []
            for oc in (g[1] or []):
                if isinstance(oc, (list, tuple)) and len(oc) >= 2:
                    oc_key = oc[0]
                    if isinstance(oc_key, (list, tuple)) and oc_key:
                        oc_types.append(oc_key[0])
                    prices.append(round(oc[1] / 100, 2) if isinstance(oc[1], (int, float)) else oc[1])
            if oc_types and mtype not in result:
                result[mtype] = (oc_types, prices)
    return req_id, result


def get_event_ids_from_page(page) -> list:
    """Capture event IDs from the WS frames on the football page."""
    frames_recv = []
    frames_sent = []
    last_recv   = [time.time()]

    def handle_ws(ws):
        if 'direct-feed' not in ws.url:
            return
        ws.on('framereceived', lambda p: (frames_recv.append(p), last_recv.__setitem__(0, time.time())) if isinstance(p, bytes) else None)
        ws.on('framesent',     lambda p: frames_sent.append(p) if isinstance(p, bytes) else None)

    page.on('websocket', handle_ws)
    page.goto(f'{BASE_SITE}/sport/football', wait_until='domcontentloaded', timeout=60_000)
    time.sleep(8)
    for _ in range(4):
        page.mouse.wheel(0, 700)
        time.sleep(0.5)
    deadline = time.time() + 15
    while time.time() < deadline:
        time.sleep(1)
        if time.time() - last_recv[0] > 3.0 and frames_recv:
            break
    try:
        page.remove_listener('websocket', handle_ws)
    except Exception:
        pass

    # Extract event IDs from GetMainMarketsByProfileAndEventIds sent frames
    event_ids = []
    for frame in frames_sent:
        decoded = _decode_frame(frame)
        if not decoded or not isinstance(decoded, (list, tuple)):
            continue
        if len(decoded) >= 5 and decoded[3] == 'GetMainMarketsByProfileAndEventIds':
            args = decoded[4]
            if isinstance(args, (list, tuple)) and len(args) >= 2:
                ids = args[1]
                if isinstance(ids, (list, tuple)):
                    event_ids.extend(ids)

    return list(dict.fromkeys(event_ids))[:6]  # dedupe, cap at 6


if __name__ == '__main__':
    # Step 1: get some event IDs via browser
    print('Step 1: Getting event IDs via browser...')
    pw_worker = _Surebet247Worker()
    event_ids = pw_worker.call(get_event_ids_from_page, timeout=120)
    print(f'  Got {len(event_ids)} event IDs: {event_ids}')

    if not event_ids:
        print('No event IDs captured. Exiting.')
        sys.exit(1)

    # Step 2: connect directly from Python and probe profiles
    print('\nStep 2: Probing profiles via direct WS connection...\n')

    replies   = {}
    lock      = threading.Lock()
    connected = threading.Event()
    req_id    = [100]

    pending    = {}   # req_id → profile

    def on_open(ws):
        connected.set()

    def on_message(ws, msg):
        if not isinstance(msg, bytes):
            return
        rid, market_data = decode_market_types(msg)
        if rid is not None and rid in pending:
            with lock:
                replies[rid] = market_data

    def on_error(ws, err):
        print(f'WS error: {err}')

    ws = websocket.WebSocketApp(
        WS_URL,
        on_open=on_open,
        on_message=on_message,
        on_error=on_error,
    )
    t = threading.Thread(target=lambda: ws.run_forever(), daemon=True)
    t.start()

    if not connected.wait(timeout=15):
        print('WS connection timed out')
        sys.exit(1)

    print('Connected to WS. Sending profile probes...\n')

    # Send one request per profile
    for profile in PROFILES_TO_TRY:
        rid = req_id[0]
        req_id[0] += 1
        pending[rid] = profile
        frame = encode_rpc(rid, 'GetMainMarketsByProfileAndEventIds',
                           [profile, event_ids, 4, 1, CONTEXT])
        ws.send(frame, opcode=websocket.ABNF.OPCODE_BINARY)
        time.sleep(0.3)

    # Wait for replies
    time.sleep(4)
    ws.close()

    # Print results
    for rid, profile in sorted(pending.items()):
        mkt_data = replies.get(rid)
        if mkt_data is None:
            print(f'  {profile!r:25s} → no reply')
        elif not mkt_data:
            print(f'  {profile!r:25s} → empty / error')
        else:
            type_ids = sorted(mkt_data.keys())
            print(f'  {profile!r:25s} → market_type_ids: {type_ids}')
            for mtype in type_ids:
                oc_types, prices = mkt_data[mtype]
                print(f'    type={mtype:<5} outcomes={oc_types}  prices={prices}')
