"""Cross-venue soccer coverage audit: Kalshi x Poly-US x Poly.com x API-Football.

WHY THIS EXISTS. On 2026-07-29 I made FOUR wrong "not covered" claims in one
session, every one of them a failed lookup rather than a real absence:

  1. "Kalshi has no Swiss match-winner series" -- I queried /series with
     limit=200; KXSWISSLEAGUEGAME was on a later page.
  2. "Poly-US has no Swiss coverage" -- I searched their catalogue for the string
     "swiss"; the league slug is `swsl`, and /v2/leagues returns the same 50 rows
     no matter what limit/offset you pass, so it is never in the response at all.
  3. "Poly-US has no Brazilian events" -- I passed the DIV code 'BSA' to
     league_events(), which wants the SLUG 'bra'. Got 0 and believed it.
  4. "API-Football has a 6-8% Pinnacle coverage tail" -- three of my four
     examples were POSTPONED fixtures, which have no line because they have no
     match.

The common failure: a name-based spot check returning empty, treated as evidence
of absence. The fix is to ENUMERATE each venue's own catalogue and cross-
reference, so "missing" means "absent from a full listing" rather than "my search
string did not match".

METHOD, and its deliberate paranoia:
  - Kalshi: page /series to exhaustion (cursor), keep every *GAME series, then
    count OPEN events per series. A series with no open events is listed but not
    currently tradeable, which is a different fact and reported separately.
  - Poly-US: /v2/leagues is UNRELIABLE (ignores paging), so instead probe each
    candidate slug directly via league_events(slug). Slug guesses come from our
    own map plus the observed pattern (e.g. `swsl`), and anything that returns
    events is real regardless of whether the catalogue admits it exists.
  - Poly.com: probe league tags the same way.
  - API-Football: search /leagues by country, since that is the axis it indexes
    on; a name search misses leagues whose name differs from ours.

NOTHING here is evidence of absence unless the venue returned a full listing.
Where a lookup fails, the output says UNKNOWN, not "no".

Usage:  python research\\venue_coverage_audit.py [--full]
"""
import json
import sys
from collections import defaultdict

import requests

sys.path.insert(0, r'E:\soccer\main')
import kalshi_trader as kt
import poly_us_prices as PUS
import live_monitor as LM
import maps

GATEWAY = 'https://gateway.polymarket.us'


def kalshi_game_series():
    """Every *GAME series, paged to exhaustion. Returns {ticker: title}."""
    out, cursor = {}, None
    while True:
        p = {'category': 'Sports', 'limit': 200}
        if cursor:
            p['cursor'] = cursor
        try:
            d = kt._get('/series', p)
        except Exception as e:
            print(f'  [kalshi] series page failed: {e}')
            break
        batch = d.get('series', [])
        for s in batch:
            t = str(s.get('ticker', ''))
            if t.endswith('GAME'):
                out[t] = s.get('title', '')
        cursor = d.get('cursor')
        if not cursor or not batch:
            break
    return out


def kalshi_open_events(ticker):
    try:
        d = kt._get('/events', {'series_ticker': ticker, 'status': 'open', 'limit': 100})
        return len(d.get('events', []))
    except Exception:
        return None          # UNKNOWN, not zero


def polyus_probe(slug):
    """Events for a Poly-US league slug. None = lookup failed (UNKNOWN)."""
    try:
        return len(PUS.league_events(slug) or [])
    except Exception:
        return None


def main():
    full = '--full' in sys.argv
    print('KALSHI — every match-winner (*GAME) series, paged to exhaustion')
    ks = kalshi_game_series()
    print(f'  {len(ks)} *GAME series found\n')

    # soccer-ish filter, but print everything under --full so nothing is hidden
    SOCCER_HINT = ('league', 'liga', 'serie', 'premier', 'soccer', 'division',
                   'eredivisie', 'bundesliga', 'superliga', 'ekstraklasa',
                   'allsvenskan', 'eliteserien', 'uefa', 'cup', 'mls', 'primera')
    rows = []
    for t, title in sorted(ks.items()):
        if not full and not any(h in title.lower() for h in SOCCER_HINT):
            continue
        rows.append((t, title))

    print(f"  {'series':30s} {'open events':>11s}  title")
    wired = {maps.league_kalshi_series(d) for d in maps.all_divs()}
    for t, title in rows:
        n = kalshi_open_events(t)
        tag = 'WIRED' if t in wired else ''
        ns = 'UNKNOWN' if n is None else str(n)
        print(f'  {t:30s} {ns:>11s}  {title[:40]:40s} {tag}')

    print('\nPOLY-US — probing slugs directly (/v2/leagues ignores paging, so a')
    print('          catalogue miss proves nothing)')
    slugs = dict(PUS.LEAGUE_SLUG)
    extra = {'SWISS?': 'swsl'}     # discovered from an event URL, absent from /v2/leagues
    for label, s in list(slugs.items()) + list(extra.items()):
        n = polyus_probe(s)
        ns = 'UNKNOWN' if n is None else str(n)
        print(f'  {str(label):8s} slug={s:8s} events={ns}')

    print('\nAPI-FOOTBALL — Pinnacle availability is the binding constraint for the')
    print('               maker; a league with no fair value cannot be quoted.')
    print('  (run with a country to check: /leagues?country=<name>)')


if __name__ == '__main__':
    main()
