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

from __future__ import annotations

from src.core.numbers import safe_float
from src.core.types import JsonDict
from src.trading.market_analysis.htf import (
    safe_market_phase,
    safe_market_state,
    safe_trend_direction,
    safe_trend_quality,
    safe_trend_strength,
    safe_volatility_state,
)
from src.trading.market_analysis.models import (
    EmaDistanceState,
    EntryTimingState,
    MarketAnalysisResult,
    MarketPhase,
    MarketState,
    MarketStructure,
    MomentumState,
    TrendDirection,
    TrendQuality,
    TrendStrength,
    VolatilityState,
)


def build_market_analysis_result(
    *,
    symbol: str,
    interval: str,
    state: MarketState,
    trend: TrendDirection,
    volatility: VolatilityState,
    close_price: float,
    ema_fast: float,
    ema_slow: float,
    atr_value: float,
    atr_percent: float,
    rsi_value: float | None,
    candles_count: int,
    reason: str,
    is_trade_allowed: bool,
    payload: JsonDict,
    trend_strength: TrendStrength,
    trend_quality: TrendQuality,
    market_phase: MarketPhase,
    market_structure: MarketStructure,
    market_structure_reason: str,
    trend_gap_percent: float | None,
    trend_consistency: float | None,
    trend_efficiency: float | None,
    ema_distance_atr_ratio: float | None,
    phase_direction: TrendDirection,
    phase_change_percent: float | None,
    phase_reason: str | None,
    ema_fast_slope_percent: float | None,
    ema_slow_slope_percent: float | None,
    phase_direction_consistency: float | None,
    current_interval_change_percent: float | None,
    current_interval_direction: TrendDirection,
    current_interval_label: str,
    momentum_state: MomentumState,
    momentum_direction: TrendDirection,
    momentum_change_percent: float | None,
    momentum_strength: float | None,
    breakout_level: float | None,
    breakout_distance_percent: float | None,
    breakout_reason: str | None,
    trend_quality_score_value: float | None,
    ema_distance_state: EmaDistanceState,
    entry_timing_state: EntryTimingState,
    entry_timing_reason: str | None,
    htf_interval: str,
    htf_context: JsonDict | None,
    htf_trend_context: JsonDict | None,
    market_score: int | None = None,
    market_score_label: str | None = None,
    market_long_score: int | None = None,
    market_short_score: int | None = None,
) -> MarketAnalysisResult:
    # HTF-контексты могут быть пустыми/None, если анализ старшего ТФ
    # не выполнился или вернул fallback. Защищаем .get(...) ниже.
    htf_context = htf_context or {}
    htf_trend_context = htf_trend_context or {}

    return MarketAnalysisResult(
        symbol=symbol,
        interval=interval,
        state=state,
        trend=trend,
        volatility=volatility,
        close_price=close_price,
        ema_fast=ema_fast,
        ema_slow=ema_slow,
        atr=atr_value,
        atr_percent=atr_percent,
        rsi=rsi_value,
        candles_count=candles_count,
        reason=reason,
        is_trade_allowed=is_trade_allowed,
        payload=payload,
        trend_strength=trend_strength,
        trend_quality=trend_quality,
        market_phase=market_phase,
        market_structure=market_structure,
        market_structure_reason=market_structure_reason,
        trend_gap_percent=trend_gap_percent,
        trend_consistency=trend_consistency,
        trend_efficiency=trend_efficiency,
        ema_distance_atr_ratio=ema_distance_atr_ratio,
        phase_direction=phase_direction,
        phase_change_percent=phase_change_percent,
        phase_reason=phase_reason,
        ema_fast_slope_percent=ema_fast_slope_percent,
        ema_slow_slope_percent=ema_slow_slope_percent,
        phase_direction_consistency=phase_direction_consistency,
        current_interval_change_percent=current_interval_change_percent,
        current_interval_direction=current_interval_direction,
        current_interval_label=current_interval_label,
        momentum_state=momentum_state,
        momentum_direction=momentum_direction,
        momentum_change_percent=momentum_change_percent,
        momentum_strength=momentum_strength,
        breakout_level=breakout_level,
        breakout_distance_percent=breakout_distance_percent,
        breakout_reason=breakout_reason,

        # HTF volatility context.
        htf_interval=str(htf_context.get("htf_interval") or htf_interval),
        htf_atr_percent=safe_float(htf_context.get("htf_atr_percent")),
        htf_atr_percent_baseline=safe_float(
            htf_context.get("htf_atr_percent_baseline")
        ),
        htf_volatility_ratio=safe_float(
            htf_context.get("htf_volatility_ratio")
        ),
        htf_volatility=safe_volatility_state(
            htf_context.get("htf_volatility")
        ),

        # Advanced trend quality.
        trend_quality_score=trend_quality_score_value,
        ema_distance_state=ema_distance_state,
        entry_timing_state=entry_timing_state,
        entry_timing_reason=entry_timing_reason,

        # HTF trend context. Используем safe_* функции,
        # чтобы неожиданные значения не ломали диагностику.
        htf_market_state=safe_market_state(
            htf_trend_context.get("htf_market_state")
        ),
        htf_trend=safe_trend_direction(
            htf_trend_context.get("htf_trend")
        ),
        htf_trend_strength=safe_trend_strength(
            htf_trend_context.get("htf_trend_strength")
        ),
        htf_trend_quality=safe_trend_quality(
            htf_trend_context.get("htf_trend_quality")
        ),
        htf_market_phase=safe_market_phase(
            htf_trend_context.get("htf_market_phase")
        ),
        htf_alignment=str(htf_trend_context.get("htf_alignment") or ""),
        htf_confirmation_score=safe_float(
            htf_trend_context.get("htf_confirmation_score")
        ),
        htf_reason=str(htf_trend_context.get("htf_reason") or ""),

        # Общая оценка рынка для UI/diagnostics/adaptive sizing.
        market_score=market_score,
        market_score_label=market_score_label,
        market_long_score=market_long_score,
        market_short_score=market_short_score,
    )