"""Market Regime Identification."""
from __future__ import annotations

import math
from typing import Sequence

from backend.app.schemas.market import Candle
from backend.app.schemas.signal import MarketRegime


class RegimeClassifier:
    """Classifies market structure into distinct behavioral regimes using causal metrics."""

    def classify(
        self,
        prices: Sequence[float],
        fast_ema: Sequence[float],
        slow_ema: Sequence[float],
        atr: Sequence[float],
        spread_pct: float = 0.0002,
    ) -> MarketRegime:
        if len(prices) < 30 or math.isnan(fast_ema[-1]) or math.isnan(slow_ema[-1]) or math.isnan(atr[-1]):
            return MarketRegime.UNCERTAIN

        # Check for liquidity stress if spread is abnormally wide (> 0.15%)
        if spread_pct > 0.0015:
            return MarketRegime.LIQUIDITY_STRESS

        current_price = prices[-1]
        ema_f = fast_ema[-1]
        ema_s = slow_ema[-1]

        # Calculate normalized ATR volatility percentile
        recent_atrs = [a for a in atr[-30:] if not math.isnan(a)]
        current_atr = atr[-1]
        atr_percentile = (
            sum(1 for a in recent_atrs if a <= current_atr) / len(recent_atrs) if recent_atrs else 0.5
        )

        # Trending Conditions
        trend_threshold = 0.002 * current_price  # 0.2% EMA separation
        if current_price > ema_f > ema_s and (ema_f - ema_s) > trend_threshold:
            return MarketRegime.TRENDING_BULL
        elif current_price < ema_f < ema_s and (ema_s - ema_f) > trend_threshold:
            return MarketRegime.TRENDING_BEAR

        # Ranging Conditions based on ATR volatility
        if atr_percentile >= 0.70:
            return MarketRegime.RANGING_HIGH_VOL
        elif atr_percentile <= 0.30:
            return MarketRegime.RANGING_LOW_VOL

        return MarketRegime.UNCERTAIN


regime_classifier = RegimeClassifier()
