"""
Try different GetMainMarketsByProfileAndEventIds profile names to find DC.

Reuses the existing WS session: captures event IDs from a page load,
then manually sends RPC calls with different profiles and prints the
market_type_ids that come back.

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

import time, collections
import msgpack
from scrapers.surebet247 import _Surebet247Worker, _decode_frame

BASE_SITE = 'https://www.surebet247.com'

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

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


def _encode_rpc(req_id: int, method: str, args: list) -> bytes:
    """Encode a type-4 RPC request frame."""
    payload = [4, {}, req_id, method, args]
    raw = msgpack.packb(payload, use_bin_type=True)
    return b'\x00' + raw   # 1-byte length prefix


def _decode_market_types(frame: bytes) -> list:
    """Return list of (market_type_id, outcome_type_ids) from a market reply frame."""
    decoded = _decode_frame(frame)
    if not decoded or not isinstance(decoded, (list, tuple)) or decoded[0] != 2:
        return []
    if len(decoded) < 4:
        return []
    reply_data = decoded[3]
    if not isinstance(reply_data, (list, tuple)) or len(reply_data) < 2 or not reply_data[0]:
        return []
    items = reply_data[1]
    if not isinstance(items, (list, tuple)):
        return []

    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
        market_type = item_key[2]
        market_val  = item[2]
        if not isinstance(market_val, (list, tuple)) or not market_val:
            continue
        selection_groups = market_val[0]
        if not isinstance(selection_groups, (list, tuple)):
            continue
        for group in selection_groups:
            if not isinstance(group, (list, tuple)) or len(group) < 2:
                continue
            outcomes_raw = group[1]
            if not isinstance(outcomes_raw, (list, tuple)):
                continue
            oc_types = []
            prices   = []
            for oc in outcomes_raw:
                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:
                result.append((market_type, oc_types, prices))
    return result


def probe_profiles(page):
    # Step 1: capture event IDs from a normal page load
    frames_recv = []
    frames_sent = []
    event_ids   = []
    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, ws)), last_recv.__setitem__(0, time.time())) if isinstance(p, bytes) else None)
        ws.on('framesent',     lambda p: frames_sent.append((p, ws))  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

    # Extract the WS object and event IDs from the sent frames
    ws_obj = None
    for raw_frame, ws in frames_sent:
        decoded = _decode_frame(raw_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)
                ws_obj = ws
    event_ids = list(dict.fromkeys(event_ids))[:10]  # dedupe, cap at 10

    if not event_ids or ws_obj is None:
        print('Could not extract event IDs or WS object from page load')
        return

    print(f'Using {len(event_ids)} event IDs: {event_ids[:4]}...')

    # Step 2: probe each profile
    results = {}
    req_id_start = 1000

    for i, profile in enumerate(PROFILES_TO_TRY):
        req_id = req_id_start + i
        args   = [profile, event_ids[:4], 4, 1, CONTEXT]
        frame  = _encode_rpc(req_id, 'GetMainMarketsByProfileAndEventIds', args)

        # Clear recv buffer, send request, wait for reply
        reply_frames = []
        start = time.time()

        def on_recv_probe(payload, _rid=req_id):
            decoded = _decode_frame(payload)
            if (decoded and isinstance(decoded, (list, tuple))
                    and decoded[0] == 2 and str(decoded[2]) == str(_rid)):
                reply_frames.append(payload)

        ws_obj.on('framereceived', on_recv_probe)
        ws_obj.send(frame)
        time.sleep(2)  # wait for reply
        ws_obj.remove_listener('framereceived', on_recv_probe)

        if not reply_frames:
            print(f'  profile={profile!r:25s} → no reply')
            continue

        mkt_types = _decode_market_types(reply_frames[0])
        unique = {}
        for mtype, oc_types, prices in mkt_types:
            if mtype not in unique:
                unique[mtype] = (oc_types, prices)

        print(f'  profile={profile!r:25s} → market_type_ids: {sorted(unique.keys())}')
        for mtype, (oc_types, prices) in sorted(unique.items()):
            print(f'    type={mtype:<5} outcomes={oc_types}  prices={prices}')

    return results


if __name__ == '__main__':
    worker = _Surebet247Worker()
    print('Browser ready. Loading football page and probing profiles...\n')
    worker.call(probe_profiles, timeout=180)
