from __future__ import annotations

from dataclasses import dataclass
from typing import Any

from therminal.models._base import DictLikeMixin


@dataclass(frozen=True)
class Level:
    price: int
    qty: int

    @classmethod
    def from_api_dict(cls, d: dict[str, Any]) -> Level:
        return cls(
            price=d.get("price", 0),
            qty=d.get("qty", 0),
        )


@dataclass(frozen=True)
class LOBSnapshot(DictLikeMixin):
    ts: int
    market_id: str
    best_bid: int
    best_ask: int
    spread: int
    mid: float
    bids: tuple[Level, ...]
    asks: tuple[Level, ...]

    @classmethod
    def from_api_dict(cls, d: dict[str, Any]) -> LOBSnapshot:
        raw_bids = d.get("bids") or []
        raw_asks = d.get("asks") or []
        return cls(
            ts=d.get("ts", 0),
            market_id=d.get("market_id", ""),
            best_bid=d.get("best_bid", 0),
            best_ask=d.get("best_ask", 0),
            spread=d.get("spread", 0),
            mid=float(d.get("mid", 0.0)),
            bids=tuple(Level.from_api_dict(b) for b in raw_bids),
            asks=tuple(Level.from_api_dict(a) for a in raw_asks),
        )

    def to_dict(self) -> dict[str, Any]:
        return {
            "ts": self.ts,
            "market_id": self.market_id,
            "best_bid": self.best_bid,
            "best_ask": self.best_ask,
            "spread": self.spread,
            "mid": self.mid,
            "bids": [{"price": lv.price, "qty": lv.qty} for lv in self.bids],
            "asks": [{"price": lv.price, "qty": lv.qty} for lv in self.asks],
        }
