# app/src/trading/market_analysis/reason.py

from __future__ import annotations

from src.trading.market_analysis.models import (
    EmaDistanceState,
    EntryTimingState,
    MarketPhase,
    MarketState,
    MomentumState,
    TrendQuality,
    TrendStrength,
    VolatilityState,
)


def build_market_reason(
    *,
    state: MarketState,
    volatility: VolatilityState,
    atr_percent: float,
    rsi_value: float | None,
    trend_strength: TrendStrength,
    trend_quality: TrendQuality,
    market_phase: MarketPhase,
    momentum_state: MomentumState,
    candle_noise_score: float | None,
    price_position_score: float | None,
    ema_distance_state: EmaDistanceState,
    entry_timing_state: EntryTimingState,
    min_clean_candle_score: float,
    min_price_position_score: float,
    rsi_overbought: float = 72.0,
    rsi_oversold: float = 28.0,
) -> str:
    reasons: list[str] = []

    def add(text: str) -> None:
        # Не даём одинаковым причинам дублироваться в итоговой строке.
        if text and text not in reasons:
            reasons.append(text)

    if state == MarketState.TREND_UP:
        add("Рынок растёт")
    elif state == MarketState.TREND_DOWN:
        add("Рынок снижается")
    elif state == MarketState.RANGE:
        add("Рынок во флэте")
    elif state == MarketState.HIGH_VOLATILITY:
        add("Рынок слишком волатилен")
    elif state == MarketState.LOW_VOLATILITY:
        add("Рынок малоподвижен")
    else:
        add("Состояние рынка не определено")

    if trend_strength == TrendStrength.STRONG:
        add("Сильный тренд")
    elif trend_strength == TrendStrength.NORMAL:
        add("Нормальный тренд")
    elif trend_strength == TrendStrength.WEAK:
        add("Слабый тренд")

    if trend_quality == TrendQuality.CLEAN:
        add("Движение чистое")
    elif trend_quality == TrendQuality.NORMAL:
        add("Нормальное качество тренда")
    elif trend_quality == TrendQuality.NOISY:
        add("Движение шумное")

    if market_phase == MarketPhase.IMPULSE:
        add("Фаза импульса")
    elif market_phase == MarketPhase.PULLBACK:
        add("Фаза отката")
    elif market_phase == MarketPhase.RANGE:
        add("Фаза флэта")
    elif market_phase == MarketPhase.SQUEEZE:
        add("Фаза сжатия")

    if momentum_state == MomentumState.BREAKOUT_UP:
        add("Пробой вверх")
    elif momentum_state == MomentumState.BREAKOUT_DOWN:
        add("Пробой вниз")
    elif momentum_state == MomentumState.MOMENTUM_UP:
        add("Импульс вверх")
    elif momentum_state == MomentumState.MOMENTUM_DOWN:
        add("Импульс вниз")
    elif momentum_state == MomentumState.NONE:
        add("Сильного импульса нет")

    if ema_distance_state == EmaDistanceState.COMPRESSED:
        add("EMA сильно сжаты")
    elif ema_distance_state == EmaDistanceState.HEALTHY:
        add("EMA-дистанция здоровая")
    elif ema_distance_state == EmaDistanceState.EXTENDED:
        add("Тренд расширен")
    elif ema_distance_state == EmaDistanceState.OVEREXTENDED:
        add("Тренд перерастянут")

    if entry_timing_state == EntryTimingState.EARLY:
        add("Ранняя зона входа")
    elif entry_timing_state == EntryTimingState.NORMAL:
        add("Тайминг входа нормальный")
    elif entry_timing_state == EntryTimingState.LATE:
        add("Поздний вход")
    elif entry_timing_state == EntryTimingState.CHASING:
        add("Вход запрещён: chasing move")

    if rsi_value is not None:
        if rsi_value >= rsi_overbought:
            add("RSI в зоне перекупленности")
        elif rsi_value <= rsi_oversold:
            add("RSI в зоне перепроданности")

    if candle_noise_score is not None and candle_noise_score < min_clean_candle_score:
        add("Свечи шумные")

    if price_position_score is not None:
        if price_position_score >= min_price_position_score:
            add("Цена держится по тренду")
        else:
            add("Цена плохо держится по тренду")

    if volatility == VolatilityState.HIGH:
        add("Высокая волатильность")
    elif volatility == VolatilityState.LOW:
        add("Низкая волатильность")
    elif volatility == VolatilityState.NORMAL:
        add("Нормальная волатильность")

    if not reasons:
        add("Рынок анализируется")

    rsi_text = f", RSI={rsi_value:.2f}" if rsi_value is not None else ""

    return f"{'. '.join(reasons)}. ATR={atr_percent:.2f}%{rsi_text}."