# app/tests/unit/trading/market_analysis/test_quality_candle.py

from __future__ import annotations

from datetime import datetime, timezone
from decimal import Decimal

from src.market_data.acquisition.models.candle import Candle


def _candle(
    *,
    index: int = 0,
    open_price: str = "100",
    high_price: str = "110",
    low_price: str = "90",
    close_price: str = "105",
    volume: str = "10",
) -> Candle:
    return Candle(
        symbol="BTC/USD_LEVERAGE",
        interval="1m",
        open_time=datetime.fromtimestamp(
            1_750_000_000 + index * 60,
            tz=timezone.utc,
        ),
        open_price=Decimal(open_price),
        high_price=Decimal(high_price),
        low_price=Decimal(low_price),
        close_price=Decimal(close_price),
        volume=Decimal(volume),
        source="test",
    )


from src.trading.market_analysis.quality import candle_noise_score


def test_candle_noise_score_accepts_decimal_candles() -> None:
    candles = [
        _candle(
            index=0,
            open_price="91",
            high_price="100",
            low_price="90",
            close_price="99",
        ),
        _candle(
            index=1,
            open_price="94",
            high_price="100",
            low_price="90",
            close_price="96",
        ),
    ]

    result = candle_noise_score(
        candles,
        candle_noise_window=2,
        min_clean_body_ratio=0.5,
    )

    assert result == 0.5
    assert isinstance(result, float)


def test_candle_noise_score_returns_none_for_empty_sequence() -> None:
    assert (
        candle_noise_score(
            [],
            candle_noise_window=10,
            min_clean_body_ratio=0.5,
        )
        is None
    )


def test_candle_noise_score_skips_zero_range_candle() -> None:
    candles = [
        _candle(
            index=0,
            open_price="100",
            high_price="100",
            low_price="100",
            close_price="100",
        ),
        _candle(
            index=1,
            open_price="91",
            high_price="100",
            low_price="90",
            close_price="99",
        ),
    ]

    result = candle_noise_score(
        candles,
        candle_noise_window=2,
        min_clean_body_ratio=0.5,
    )

    assert result == 1.0


def test_candle_noise_score_skips_non_finite_decimal_value() -> None:
    candles = [
        _candle(
            index=0,
            high_price="NaN",
        ),
    ]

    assert (
        candle_noise_score(
            candles,
            candle_noise_window=1,
            min_clean_body_ratio=0.5,
        )
        is None
    )


def test_candle_noise_score_uses_requested_tail_window() -> None:
    candles = [
        _candle(
            index=0,
            open_price="91",
            high_price="100",
            low_price="90",
            close_price="99",
        ),
        _candle(
            index=1,
            open_price="94",
            high_price="100",
            low_price="90",
            close_price="96",
        ),
        _candle(
            index=2,
            open_price="92",
            high_price="100",
            low_price="90",
            close_price="98",
        ),
    ]

    result = candle_noise_score(
        candles,
        candle_noise_window=2,
        min_clean_body_ratio=0.5,
    )

    assert result == 0.5
