import math

from app.schemas.schemas import PriceData
from app.services.ai_context_builder import AIContextBuilder


def _build_sample_price_data(bars: int = 220) -> list[PriceData]:
    base_price = 1950.0
    price_data: list[PriceData] = []
    for i in range(bars):
        drift = i * 0.25
        wave = math.sin(i / 7.0) * 3.0
        close = base_price + drift + wave
        high = close + 0.8
        low = close - 0.8
        open_price = close - math.sin(i / 11.0) * 0.5
        price_data.append(
            PriceData(
                time=i,
                open=open_price,
                high=high,
                low=low,
                close=close,
                volume=1000 + i,
            )
        )
    return price_data


def test_build_metrics_includes_enhanced_indicators():
    price_data = _build_sample_price_data()
    builder = AIContextBuilder()

    metrics = builder.build_metrics("XAUUSD", "1m", price_data)

    assert metrics.bb_basis is not None
    assert metrics.bb_upper is not None
    assert metrics.bb_lower is not None
    assert metrics.rsi3 is not None
    assert metrics.zlsma is not None
    assert metrics.chandelier_long_stop is not None
    assert metrics.chandelier_short_stop is not None
    assert metrics.chandelier_signal in {None, "LONG", "SHORT", "NEUTRAL"}
    assert metrics.bb_signal in {None, "LONG", "SHORT"}


def test_indicator_payload_emits_enhanced_metrics():
    price_data = _build_sample_price_data()
    builder = AIContextBuilder()
    bars = [
        {
            "time": item.time,
            "open": item.open,
            "high": item.high,
            "low": item.low,
            "close": item.close,
            "volume": item.volume,
        }
        for item in price_data
    ]

    indicator_payload = builder._build_indicators(bars)  # type: ignore[attr-defined]
    indicator_names = {entry["name"] for entry in indicator_payload}

    assert "RSI_3" in indicator_names
    assert "BB_20_BASIS" in indicator_names
    assert "BB_20_UPPER" in indicator_names
    assert "BB_20_LOWER" in indicator_names
    assert "ZLSMA_50" in indicator_names
    assert "CHAND_22_LONG" in indicator_names
    assert "CHAND_22_SHORT" in indicator_names


def test_candlestick_patterns_detected():
    candles = [
        PriceData(time=0, open=100.0, high=101.0, low=99.0, close=99.0, volume=1000),
        PriceData(time=1, open=99.2, high=100.0, low=95.2, close=95.5, volume=1005),
    PriceData(time=2, open=95.0, high=101.2, low=94.8, close=100.8, volume=1010),  # Bullish engulfing candle
    PriceData(time=3, open=100.1, high=100.4, low=99.9, close=100.12, volume=1015),  # Doji
        PriceData(time=4, open=99.8, high=100.2, low=95.5, close=99.7, volume=1020),  # Long lower shadow
    ]

    builder = AIContextBuilder()
    metrics = builder.build_metrics("XAUUSD", "1m", candles)

    names = {signal.pattern for signal in metrics.pattern_signals}

    assert "Bullish Engulfing" in names
    assert "Doji" in names
    assert "Long Lower Shadow" in names
