"""
Unit tests for Alpaca raw → domain event parsing.
"""
import pytest
from app.providers.alpaca import AlpacaProvider
from app.domain.events import EventType


@pytest.fixture
def provider():
    return AlpacaProvider()


# ── Trade parsing ──────────────────────────────────────────────────────

ALPACA_TRADE_RAW = {
    "T": "t",
    "S": "AAPL",
    "p": 185.50,
    "s": 100,
    "t": "2024-01-15T14:30:00.123456Z",
    "i": 12345,
    "x": "V",
    "z": "C",
}


def test_parse_trade_basic(provider):
    event = provider._parse(ALPACA_TRADE_RAW)
    assert event is not None
    assert event.event_type == EventType.TRADE
    assert event.symbol == "AAPL"
    assert event.price == 185.50
    assert event.size == 100
    assert event.trade_id == "12345"
    assert event.provider == "alpaca"


def test_parse_trade_timestamp(provider):
    event = provider._parse(ALPACA_TRADE_RAW)
    assert event.ts_exchange is not None
    assert event.ts_exchange.year == 2024
    assert event.ts_exchange.month == 1


# ── Quote parsing ──────────────────────────────────────────────────────

ALPACA_QUOTE_RAW = {
    "T": "q",
    "S": "TSLA",
    "bp": 250.10,
    "bs": 200,
    "ap": 250.25,
    "as": 150,
    "t": "2024-01-15T14:30:01.456789Z",
    "x": "V",
    "z": "C",
}


def test_parse_quote_basic(provider):
    event = provider._parse(ALPACA_QUOTE_RAW)
    assert event is not None
    assert event.event_type == EventType.QUOTE
    assert event.symbol == "TSLA"
    assert event.bid == 250.10
    assert event.ask == 250.25
    assert event.bid_size == 200
    assert event.ask_size == 150
    assert event.provider == "alpaca"


# ── Control messages ───────────────────────────────────────────────────

def test_parse_success_message(provider):
    raw = {"T": "success", "msg": "connected"}
    event = provider._parse(raw)
    assert event is None


def test_parse_subscription_message(provider):
    raw = {"T": "subscription", "trades": ["AAPL"], "quotes": ["AAPL"]}
    event = provider._parse(raw)
    assert event is None


def test_parse_error_message(provider):
    raw = {"T": "error", "code": 402, "msg": "auth failed"}
    event = provider._parse(raw)
    assert event is None


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

def test_parse_trade_missing_timestamp(provider):
    raw = {"T": "t", "S": "AAPL", "p": 100, "s": 10, "i": 1}
    event = provider._parse(raw)
    assert event is not None
    assert event.ts_exchange is None


def test_parse_quote_zero_values(provider):
    raw = {"T": "q", "S": "SPY", "bp": 0, "bs": 0, "ap": 0, "as": 0}
    event = provider._parse(raw)
    assert event is not None
    assert event.bid == 0
    assert event.ask == 0
