# app/tests/unit/market_data/acquisition/validation/test_quote_values.py

from __future__ import annotations

import pytest

from src.market_data.acquisition.adapters.dzengi.models import (
    DzengiTicker24hrResponse,
)
from src.market_data.acquisition.exceptions import QuoteValueError
from src.market_data.acquisition.validation.values import validate_quote_values


def _response(
    *,
    symbol: str = "BTC/USD_LEVERAGE",
    last_price: str | int | float = "64159.45",
    bid_price: str | int | float = "64159.45",
    ask_price: str | int | float = "64159.55",
    close_time: int = 1783887270312,
) -> DzengiTicker24hrResponse:
    return DzengiTicker24hrResponse(
        symbol=symbol,
        last_price=last_price,
        bid_price=bid_price,
        ask_price=ask_price,
        close_time=close_time,
    )


def test_validate_quote_values_accepts_real_response() -> None:
    validate_quote_values(_response())


@pytest.mark.parametrize(
    ("field_name", "value"),
    [
        ("last_price", "0"),
        ("bid_price", "-1"),
        ("ask_price", "NaN"),
        ("last_price", "not-a-number"),
    ],
)
def test_validate_quote_values_rejects_invalid_price(
    field_name: str,
    value: str,
) -> None:
    values = {
        "last_price": "64159.45",
        "bid_price": "64159.45",
        "ask_price": "64159.55",
    }
    values[field_name] = value

    with pytest.raises(QuoteValueError):
        validate_quote_values(
            _response(
                last_price=values["last_price"],
                bid_price=values["bid_price"],
                ask_price=values["ask_price"],
            )
        )


def test_validate_quote_values_rejects_empty_symbol() -> None:
    with pytest.raises(QuoteValueError, match="symbol"):
        validate_quote_values(_response(symbol="   "))


def test_validate_quote_values_rejects_non_positive_close_time() -> None:
    with pytest.raises(QuoteValueError, match="closeTime"):
        validate_quote_values(_response(close_time=0))


def test_validate_quote_values_rejects_crossed_market() -> None:
    with pytest.raises(QuoteValueError, match="bidPrice"):
        validate_quote_values(
            _response(
                bid_price="64160.00",
                ask_price="64159.55",
            )
        )


def test_validate_quote_values_accepts_equal_bid_and_ask() -> None:
    validate_quote_values(
        _response(
            bid_price="64159.45",
            ask_price="64159.45",
        )
    )
