"""
Click into a Surebet247 event and capture ALL market types on the detail page.

The listing page only loads 'pro_main_period'. Clicking into an event
may trigger a different RPC profile/method that includes BTTS.

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

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

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


def capture_event_page_markets(page) -> dict:
    results = {
        'methods_sent': [],
        'market_samples': collections.defaultdict(list),
    }

    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)

    # ── Step 1: load football listing page ────────────────────────────────────
    print('  Loading listing page...')
    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)
    time.sleep(4)

    # Print current URL and page title
    print(f'  URL after load: {page.url}')

    # ── Step 2: click the first event card ───────────────────────────────────
    clicked = False

    # Try various selectors that likely wrap individual events
    selectors = [
        '[class*="event-row"]',
        '[class*="EventRow"]',
        '[class*="match-row"]',
        '[class*="event-item"]',
        '[class*="EventItem"]',
        '[class*="event-card"]',
        '[class*="prematch"] [class*="event"]',
        '[class*="sport-event"]',
        '[data-event-id]',
        '[class*="table-row"]',
        # generic: any element under a list that looks clickable
        'main li:first-child',
        'main > * [class*="row"]:first-child',
    ]

    for sel in selectors:
        try:
            el = page.query_selector(sel)
            if el and el.is_visible():
                print(f'  Clicking element matching: {sel}')
                el.click()
                clicked = True
                break
        except Exception:
            continue

    if not clicked:
        # Dump DOM classes to debug
        print('  Could not find event row. Dumping top-level class names...')
        try:
            classes = page.evaluate("""() => {
                const els = document.querySelectorAll('main *');
                const seen = new Set();
                for (const el of els) {
                    for (const c of el.classList) seen.add(c);
                    if (seen.size > 80) break;
                }
                return [...seen].slice(0, 80);
            }""")
            print(f'  Classes: {classes}')
        except Exception as e:
            print(f'  Error dumping classes: {e}')
        # Try clicking at a fixed coordinate where an event row typically appears
        print('  Trying click at y=300 (where first event typically renders)...')
        try:
            page.mouse.click(640, 300)
            clicked = True
        except Exception as e:
            print(f'  Click error: {e}')

    if clicked:
        print(f'  URL after click: {page.url}')
        time.sleep(2)
        print(f'  URL after wait: {page.url}')
        time.sleep(8)

        deadline = time.time() + 20
        while time.time() < deadline:
            time.sleep(1)
            if time.time() - last_recv[0] > 4.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 total')

    # ── Step 3: decode all 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:
            rid    = str(d[2])
            method = str(d[3])
            args   = d[4] if len(d) > 4 else []
            if method not in {m for m in method_by_id.values()}:
                results['methods_sent'].append({
                    'method': method,
                    'args_preview': str(args)[:300],
                })
            method_by_id[rid] = method

    print('\n  All methods sent:')
    seen = set()
    for item in results['methods_sent']:
        m = item['method']
        if m not in seen:
            seen.add(m)
            print(f'    {m}')
            print(f'      {item["args_preview"]}')

    # ── Step 4: parse ALL reply frames for market types ──────────────────────
    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
        rid = str(d[2])
        if rid not in method_by_id:
            continue

        reply = d[3]
        if not isinstance(reply, (list, tuple)) or len(reply) < 2 or not reply[0]:
            continue
        items = reply[1]
        if not isinstance(items, (list, tuple)):
            continue

        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]
            period      = item_key[3] if len(item_key) > 3 else None
            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 group in sgs:
                if not isinstance(group, (list, tuple)) or len(group) < 2:
                    continue
                specifiers = group[0]
                outcomes   = group[1]
                if not isinstance(outcomes, (list, tuple)):
                    continue
                sample = []
                for oc in outcomes:
                    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
                    sample.append({'type_id': oc_type, 'price': price})
                if sample:
                    results['market_samples'][(market_type, period)].append(
                        {'specifiers': specifiers, 'outcomes': sample}
                    )

    return results


if __name__ == '__main__':
    print('Starting event-page market discovery...\n')
    worker = _Surebet247Worker()
    results = worker.call(capture_event_page_markets, timeout=180)

    samples = results['market_samples']
    if not samples:
        print('\nNo market data found.')
    else:
        print(f'\n\nAll market types on event page ({len(samples)} unique type+period combos):\n')
        for (mtype, period), sample_list in sorted(samples.items()):
            s = sample_list[0]
            oc_types = [o['type_id'] for o in s['outcomes']]
            prices   = [o['price']   for o in s['outcomes']]
            spec     = s['specifiers']
            print(f'  market_type={mtype:<5} period={period}  '
                  f'outcome_ids={oc_types}  prices={prices}  spec={spec}')
