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

from __future__ import annotations

from src.trading.market_analysis.models import (
    EmaDistanceState,
    EntryTimingState,
    MarketPhase,
    MomentumState,
)


def trend_quality_score(
    *,
    trend_consistency: float | None,
    trend_efficiency: float | None,
    candle_noise_score: float | None,
    price_position_score: float | None,
) -> float | None:
    values: list[float] = []

    if trend_consistency is not None:
        values.append(trend_consistency)

    if trend_efficiency is not None:
        values.append(trend_efficiency)

    if candle_noise_score is not None:
        values.append(candle_noise_score)

    if price_position_score is not None:
        values.append(price_position_score)

    if not values:
        return None

    return sum(values) / len(values)


def classify_ema_distance_state(
    ema_distance_atr_ratio: float | None,
) -> EmaDistanceState:
    if ema_distance_atr_ratio is None:
        return EmaDistanceState.UNKNOWN

    if ema_distance_atr_ratio < 0.30:
        return EmaDistanceState.COMPRESSED

    if ema_distance_atr_ratio < 1.8:
        return EmaDistanceState.HEALTHY

    if ema_distance_atr_ratio < 2.8:
        return EmaDistanceState.EXTENDED

    return EmaDistanceState.OVEREXTENDED


def classify_entry_timing(
    *,
    ema_distance_state: EmaDistanceState,
    momentum_state: MomentumState,
    momentum_strength: float | None,
    market_phase: MarketPhase,
) -> tuple[EntryTimingState, str]:
    strength = momentum_strength or 0.0

    if ema_distance_state == EmaDistanceState.OVEREXTENDED:
        return EntryTimingState.CHASING, "EMA_OVEREXTENDED"

    if (
        ema_distance_state == EmaDistanceState.EXTENDED
        and momentum_state in {
            MomentumState.BREAKOUT_UP,
            MomentumState.BREAKOUT_DOWN,
        }
        and strength >= 1.5
    ):
        return EntryTimingState.LATE, "BREAKOUT_ALREADY_EXTENDED"

    if market_phase == MarketPhase.PULLBACK:
        return EntryTimingState.EARLY, "PULLBACK_ENTRY_ZONE"

    if ema_distance_state == EmaDistanceState.HEALTHY:
        return EntryTimingState.NORMAL, "HEALTHY_TREND_DISTANCE"

    if ema_distance_state == EmaDistanceState.COMPRESSED:
        return EntryTimingState.UNKNOWN, "EMA_COMPRESSED"

    return EntryTimingState.UNKNOWN, "ENTRY_TIMING_UNKNOWN"