"""
Inspect the raw BTTS (market type 4) frames from Surebet247 WS.

Prints:
  - Full market key [event_id, version, market_type_id, period, ...]
  - All selection groups with specifiers + outcome type IDs + prices
  - Event names for cross-referencing with the website

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

import time
from scrapers.surebet247 import _Surebet247Worker, _decode_frame

BASE_SITE  = 'https://www.surebet247.com'
TARGET_TYPE = 4   # market type we're inspecting


def inspect_btts(page) -> dict:
    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(8):
        page.mouse.wheel(0, 700)
        time.sleep(0.6)
    deadline = time.time() + 25
    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

    print(f'  Captured {len(frames_recv)} recv / {len(frames_sent)} sent frames')

    # Build request-ID → method map from sent frames
    method_by_id = {}
    for frame in frames_sent:
        if not isinstance(frame, bytes):
            continue
        d = _decode_frame(frame)
        if d and isinstance(d, (list, tuple)) and len(d) >= 4 and d[0] == 4:
            method_by_id[str(d[2])] = str(d[3])

    rich_ids   = {rid for rid, m in method_by_id.items()
                  if m in ('GetRichEventsByTournamentIdAndStage', 'GetRichEventsByIds')}
    market_ids = {rid for rid, m in method_by_id.items()
                  if m == 'GetMainMarketsByProfileAndEventIds'}

    # Collect event names
    events = {}   # event_id → 'Home - Away'
    for frame in frames_recv:
        if not isinstance(frame, bytes):
            continue
        d = _decode_frame(frame)
        if not d or not isinstance(d, (list, tuple)) or d[0] != 2 or len(d) < 4:
            continue
        if str(d[2]) not in rich_ids:
            continue
        reply = d[3]
        if not isinstance(reply, (list, tuple)) or len(reply) < 2 or not reply[0]:
            continue
        for item in (reply[1] or []):
            if not isinstance(item, (list, tuple)) or len(item) < 3:
                continue
            item_key = item[1]
            if not isinstance(item_key, (int, str)):
                continue
            ev_data = item[2]
            if not isinstance(ev_data, (list, tuple)) or len(ev_data) < 11:
                continue
            ev_name = ev_data[6]
            comps   = ev_data[10]
            if isinstance(comps, (list, tuple)) and len(comps) >= 2:
                home = comps[0][1] if comps[0] else '?'
                away = comps[1][1] if comps[1] else '?'
                events[str(item_key)] = f'{home} vs {away}'
            elif ' - ' in str(ev_name):
                events[str(item_key)] = str(ev_name).replace(' - ', ' vs ')

    # Collect all TARGET_TYPE market entries
    btts_entries = []   # list of dicts
    for frame in frames_recv:
        if not isinstance(frame, bytes):
            continue
        d = _decode_frame(frame)
        if not d or not isinstance(d, (list, tuple)) or d[0] != 2 or len(d) < 4:
            continue
        if str(d[2]) not in market_ids:
            continue
        reply = d[3]
        if not isinstance(reply, (list, tuple)) or len(reply) < 2 or not reply[0]:
            continue
        for item in (reply[1] or []):
            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
            if item_key[2] != TARGET_TYPE:
                continue

            event_id    = str(item_key[0])
            version     = item_key[1]
            mtype       = item_key[2]
            period      = item_key[3] if len(item_key) > 3 else '?'
            extra       = item_key[4:] if len(item_key) > 4 else []

            market_val = item[2]
            if not isinstance(market_val, (list, tuple)) or not market_val:
                continue
            is_suspended_mkt = market_val[5] if len(market_val) > 5 else '?'
            selection_groups = market_val[0]

            groups_parsed = []
            for gi, group in enumerate(selection_groups or []):
                if not isinstance(group, (list, tuple)) or len(group) < 2:
                    continue
                specifiers  = group[0]
                outcomes    = group[1]
                sel_susp    = group[2] if len(group) > 2 else '?'
                ocs = []
                for oc in (outcomes or []):
                    if not isinstance(oc, (list, tuple)) or len(oc) < 2:
                        continue
                    oc_key = oc[0]
                    price_c = oc[1]
                    oc_type = oc_key[0] if isinstance(oc_key, (list, tuple)) and oc_key else '?'
                    price   = round(price_c / 100, 2) if isinstance(price_c, (int, float)) else price_c
                    ocs.append({'type_id': oc_type, 'price': price, 'raw_cents': price_c})
                groups_parsed.append({
                    'group_index': gi,
                    'specifiers':  specifiers,
                    'suspended':   sel_susp,
                    'outcomes':    ocs,
                })

            btts_entries.append({
                'event_id':       event_id,
                'event_name':     events.get(event_id, '(unknown)'),
                'version':        version,
                'market_type':    mtype,
                'period':         period,
                'extra_key':      extra,
                'mkt_suspended':  is_suspended_mkt,
                'groups':         groups_parsed,
            })

    return btts_entries


if __name__ == '__main__':
    print('Loading Surebet247 football page...')
    worker = _Surebet247Worker()
    entries = worker.call(inspect_btts, timeout=120)

    if not entries:
        print('\nNo market type 4 entries found.')
        print('This means BTTS is either not in the pro_main_period profile,')
        print('or the market type ID is different from 4.')
    else:
        print(f'\nFound {len(entries)} market-type-4 entries across events.\n')
        seen_events = set()
        unique_periods = set()
        for e in entries:
            unique_periods.add(e['period'])

        print(f'Unique period values seen: {sorted(unique_periods)}\n')
        print('─' * 72)

        for e in entries[:20]:   # show first 20
            ev = e['event_name']
            print(f"Event:    {ev}  (id={e['event_id']})")
            print(f"Key:      type={e['market_type']}  period={e['period']}  "
                  f"version={e['version']}  extra={e['extra_key']}")
            print(f"Mkt suspended: {e['mkt_suspended']}")
            for g in e['groups']:
                susp = g['suspended']
                spec = g['specifiers']
                ocs  = g['outcomes']
                oc_str = '  '.join(f"type_id={o['type_id']} price={o['price']}" for o in ocs)
                print(f"  [group {g['group_index']}] specifiers={spec}  suspended={susp}")
                print(f"    outcomes: {oc_str}")
            print()
