"""Fetch live Binance bid/ask spreads via ccxt.pro WebSocket."""

import asyncio
import csv
import datetime as dt

import ccxt.pro as ccxtpro

from config import TARGET_SYMBOLS, SNAPSHOT_COUNT, OUTPUT_CSV, OUTPUT_NOTE

# binanceus used instead of binance due to geo-restriction on api.binance.com
EXCHANGE_ID = "binanceus"


async def collect_snapshots(exchange, symbol, count):
    """Watch the order book and collect `count` top-of-book snapshots."""
    snapshots = []
    for _ in range(count):
        ob = await exchange.watch_order_book(symbol)
        best_bid = ob["bids"][0][0]
        best_ask = ob["asks"][0][0]
        spread = best_ask - best_bid
        snapshots.append(
            {
                "symbol": symbol,
                "bid": best_bid,
                "ask": best_ask,
                "spread": round(spread, 8),
                "timestamp": dt.datetime.now(dt.timezone.utc).strftime(
                    "%Y-%m-%dT%H:%M:%S.%fZ"
                ),
            }
        )
    return snapshots


async def main():
    exchange = getattr(ccxtpro, EXCHANGE_ID)()
    rows = []
    try:
        for symbol in TARGET_SYMBOLS:
            snaps = await collect_snapshots(exchange, symbol, SNAPSHOT_COUNT)
            rows.extend(snaps)
    finally:
        await exchange.close()

    # Write CSV
    fieldnames = ["symbol", "bid", "ask", "spread", "timestamp"]
    with open(OUTPUT_CSV, "w", newline="") as f:
        writer = csv.DictWriter(f, fieldnames=fieldnames)
        writer.writeheader()
        writer.writerows(rows)

    # Write method note
    with open(OUTPUT_NOTE, "w") as f:
        f.write("# How These Spreads Were Collected\n\n")
        f.write(
            "Data was streamed **live** from Binance using the "
            "**ccxt.pro WebSocket API** (`watch_order_book`).\n\n"
        )
        f.write("## Technical details\n\n")
        f.write("- **Library:** CCXT (Python, `ccxt.pro`)\n")
        f.write("- **Method:** `exchange.watch_order_book(symbol)` -- "
                "persistent WebSocket connection, not REST polling\n")
        f.write(f"- **Snapshots per symbol:** {SNAPSHOT_COUNT}\n")
        f.write(f"- **Symbols:** {', '.join(TARGET_SYMBOLS)}\n")
        f.write("- **Data points:** top-of-book best bid, best ask, "
                "and computed spread\n")
        f.write("- **Cleanup:** `await exchange.close()` called in a "
                "`try/finally` block to release the WebSocket\n\n")
        f.write(
            "Unlike yesterday's REST-polled prices (~15 min lag), these "
            "snapshots reflect the order book state at the moment the "
            "WebSocket pushed each update -- typically sub-second freshness.\n"
        )

    print(f"Wrote {len(rows)} rows to {OUTPUT_CSV}")
    print(f"Wrote method note to {OUTPUT_NOTE}")


asyncio.run(main())
