"""
Test event parsing from JSON payloads (mirrors market-data-service contracts).
"""
import json


from senpai.md_consumer.models import (
    EventType,
    TradeEvent,
    QuoteEvent,
    HeartbeatEvent,
    parse_event,
)


# ── Trade events ───────────────────────────────────────────────────────


def test_parse_trade_basic():
    data = {
        "event_type": "trade",
        "provider": "binance",
        "symbol": "BTCUSDT",
        "price": 70500.0,
        "size": 1.5,
        "ts_recv": "2026-02-09T12:00:00+00:00",
    }
    event = parse_event(data)
    assert event is not None
    assert isinstance(event, TradeEvent)
    assert event.event_type == EventType.TRADE
    assert event.symbol == "BTCUSDT"
    assert event.price == 70500.0
    assert event.size == 1.5
    assert event.provider == "binance"


def test_parse_trade_with_extra_fields():
    """Unknown fields should be silently ignored (tolerant parsing)."""
    data = {
        "event_type": "trade",
        "provider": "bybit",
        "symbol": "ETHUSDT",
        "price": 2100.0,
        "size": 10.0,
        "ts_recv": "2026-02-09T12:00:00+00:00",
        "unknown_field": "should_be_ignored",
        "another_extra": 42,
    }
    event = parse_event(data)
    assert event is not None
    assert event.symbol == "ETHUSDT"


def test_parse_trade_with_side_and_exchange_ts():
    data = {
        "event_type": "trade",
        "provider": "binance",
        "symbol": "BTCUSDT",
        "price": 70000.0,
        "size": 0.5,
        "side": "buy",
        "ts_exchange": "2026-02-09T12:00:00+00:00",
        "ts_recv": "2026-02-09T12:00:00.100+00:00",
        "trade_id": "t12345",
    }
    event = parse_event(data)
    assert event.side == "buy"
    assert event.trade_id == "t12345"
    assert event.ts_exchange is not None


# ── Quote events ───────────────────────────────────────────────────────


def test_parse_quote_basic():
    data = {
        "event_type": "quote",
        "provider": "binance",
        "symbol": "BTCUSDT",
        "bid": 70000.0,
        "ask": 70001.0,
        "bid_size": 5.0,
        "ask_size": 3.0,
        "ts_recv": "2026-02-09T12:00:00+00:00",
    }
    event = parse_event(data)
    assert isinstance(event, QuoteEvent)
    assert event.bid == 70000.0
    assert event.ask == 70001.0


def test_parse_quote_zero_values():
    data = {
        "event_type": "quote",
        "provider": "binance",
        "symbol": "BTCUSDT",
        "bid": 0.0,
        "ask": 0.0,
        "bid_size": 0.0,
        "ask_size": 0.0,
    }
    event = parse_event(data)
    assert event is not None
    assert event.bid == 0.0


# ── Heartbeat events ──────────────────────────────────────────────────


def test_parse_heartbeat():
    data = {
        "event_type": "heartbeat",
        "provider": "alpaca",
        "ts_recv": "2026-02-09T12:00:00+00:00",
    }
    event = parse_event(data)
    assert isinstance(event, HeartbeatEvent)
    assert event.provider == "alpaca"


# ── Edge cases ─────────────────────────────────────────────────────────


def test_parse_unknown_type():
    data = {"event_type": "unknown_type", "provider": "test"}
    event = parse_event(data)
    assert event is None


def test_parse_missing_type():
    data = {"provider": "test", "symbol": "BTC"}
    event = parse_event(data)
    assert event is None


def test_parse_invalid_data():
    data = {"event_type": "trade"}  # missing required fields
    event = parse_event(data)
    assert event is None


def test_parse_empty_dict():
    event = parse_event({})
    assert event is None


def test_parse_from_json_bytes():
    """Simulate actual NATS message deserialization."""
    raw = b'{"event_type":"trade","provider":"binance","symbol":"BTCUSDT","price":70500.0,"size":1.5}'
    data = json.loads(raw)
    event = parse_event(data)
    assert event is not None
    assert event.price == 70500.0
