from __future__ import annotations

from crypto_spot_bot.models import Candle
from crypto_spot_bot.patterns import PatternAnalyzer


def _candles_for_pullback() -> list[Candle]:
    candles = []
    for index in range(40):
        close = 100 + index * 0.2
        candles.append(
            Candle(
                timestamp=index,
                open=close - 0.1,
                high=close + 0.4,
                low=close - 0.4,
                close=close,
                volume=100,
                ema_20=close - 0.2,
                ema_50=close - 1.0,
                ema_200=close - 2.0,
                rsi_14=48,
                atr_14=1.0,
                volume_ma_20=100,
            )
        )
    latest = candles[-1]
    latest.close = latest.ema_20 * 1.005
    latest.open = latest.close + 0.1
    return candles


def _candles_for_stabilized_drop() -> list[Candle]:
    candles = []
    closes = [98.0, 97.3, 96.6, 95.9, 95.2, 94.8, 94.55, 94.42, 94.38, 94.40, 94.45, 94.56]
    for index in range(40):
        close = 101 - index * 0.08
        if index >= 28:
            close = closes[index - 28]
        rsi = 42
        if index >= 28:
            rsi = 30 + max(0, index - 34)
        candles.append(
            Candle(
                timestamp=index,
                open=close - 0.12,
                high=close + 0.25,
                low=close - 0.26,
                close=close,
                volume=120,
                ema_20=close + 0.35,
                ema_50=close + 0.75,
                ema_200=close + 1.4,
                rsi_14=rsi,
                atr_14=0.45,
                volume_ma_20=100,
            )
        )
    candles[-1].open = candles[-1].close - 0.20
    candles[-1].low = candles[-1].close - 0.26
    return candles


def test_pattern_analyzer_detects_trend_pullback() -> None:
    result = PatternAnalyzer().analyze(_candles_for_pullback())

    assert result.label == "трендовый откат"
    assert result.score > 0.7
    assert "откат к средней" in result.tags


def test_pattern_analyzer_detects_stabilized_drop() -> None:
    result = PatternAnalyzer().analyze(_candles_for_stabilized_drop())

    assert result.label == "стабилизация после падения"
    assert result.score >= 0.58
    assert "стабилизация после падения" in result.tags
