from __future__ import annotations

from datetime import datetime, timezone
from decimal import Decimal

import pytest

from src.market_data.acquisition.adapters.dzengi.mapper import (
    map_dzengi_websocket_quote_to_quote,
)
from src.market_data.acquisition.adapters.dzengi.models import DzengiWebSocketQuoteResponse
from src.market_data.acquisition.exceptions import QuoteMappingError


def _response(timestamp: int | None = 1000) -> DzengiWebSocketQuoteResponse:
    return DzengiWebSocketQuoteResponse(
        symbol="BTC/USD",
        bid_price="10.1",
        ask_price="10.3",
        timestamp=timestamp,
    )


def test_maps_midpoint_and_timestamps() -> None:
    received_at = datetime(2026, 7, 13, tzinfo=timezone.utc)
    result = map_dzengi_websocket_quote_to_quote(_response(), received_at=received_at)
    assert result.last_price == Decimal("10.2")
    assert result.bid_price == Decimal("10.1")
    assert result.ask_price == Decimal("10.3")
    assert result.exchange_timestamp == datetime.fromtimestamp(1, tz=timezone.utc)
    assert result.received_at is received_at
    assert result.source == "dzengi"


def test_allows_missing_exchange_timestamp() -> None:
    result = map_dzengi_websocket_quote_to_quote(
        _response(None),
        received_at=datetime.now(timezone.utc),
    )
    assert result.exchange_timestamp is None


def test_rejects_naive_received_at() -> None:
    with pytest.raises(QuoteMappingError):
        map_dzengi_websocket_quote_to_quote(
            _response(),
            received_at=datetime(2026, 7, 13),
        )
