"""
Probe Polymarket live-data WebSocket filters and print raw messages.

Example:
    python3 scripts/probe_live_data_filter.py \
      --event-slug lol-wb-we-2026-05-07 \
      --topic activity \
      --type trades
"""
from __future__ import annotations

import asyncio
import json
import os
import sys
from contextlib import suppress
from datetime import datetime, timezone
from typing import Any

import click
import websockets

ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
if ROOT not in sys.path:
    sys.path.insert(0, ROOT)


LIVE_DATA_WS = "wss://ws-live-data.polymarket.com"


def _now() -> str:
    return datetime.now(timezone.utc).isoformat()


@click.command()
@click.option("--event-slug", required=True)
@click.option("--topic", "topic_name", default="activity", show_default=True)
@click.option("--type", "msg_type", default="trades", show_default=True)
@click.option("--limit", default=0, show_default=True, help="0 means run forever")
@click.option("--reconnect-delay-seconds", default=3.0, show_default=True, type=float)
def main(event_slug: str, topic_name: str, msg_type: str, limit: int, reconnect_delay_seconds: float) -> None:
    asyncio.run(_run(event_slug, topic_name, msg_type, limit, reconnect_delay_seconds))


async def _ping(ws: Any) -> None:
    try:
        while True:
            await asyncio.sleep(10)
            await ws.send("PING")
    except Exception:
        pass


async def _run(
    event_slug: str,
    topic_name: str,
    msg_type: str,
    limit: int,
    reconnect_delay_seconds: float,
) -> None:
    subscription: dict[str, Any] = {
        "action": "subscribe",
        "subscriptions": [
            {
                "topic": topic_name,
                "type": msg_type,
                "filters": json.dumps({"event_slug": event_slug}, separators=(",", ":")),
            }
        ],
    }
    seen = 0
    while limit <= 0 or seen < limit:
        try:
            async with websockets.connect(LIVE_DATA_WS, ping_interval=None, open_timeout=10) as ws:
                await ws.send(json.dumps(subscription, separators=(",", ":")))
                print(_now(), "SUB", json.dumps(subscription, separators=(",", ":")), flush=True)
                ping_task = asyncio.create_task(_ping(ws))
                try:
                    while limit <= 0 or seen < limit:
                        raw = await ws.recv()
                        if str(raw).strip():
                            seen += 1
                        print(_now(), raw, flush=True)
                finally:
                    ping_task.cancel()
                    with suppress(asyncio.CancelledError):
                        await ping_task
        except asyncio.CancelledError:
            raise
        except Exception as exc:
            print(_now(), "RECONNECT", repr(exc), flush=True)
            await asyncio.sleep(reconnect_delay_seconds)


if __name__ == "__main__":
    main()
