"""
Market Regime Detection Service
Identifies market regime to gate trade signal generation
"""
import pandas as pd
import numpy as np
from typing import Optional
from enum import Enum
from utils.logger import logger


class MarketRegime(Enum):
    """Market regime classification"""
    TREND = "TREND"  # Trending market (continuation bias)
    RANGE = "RANGE"  # Range-bound market (fade or vol-sell bias)
    HIGH_VOL_EVENT = "HIGH_VOL_EVENT"  # High volatility event (volatility expansion bias)


class MarketRegimeDetector:
    """
    Detects market regime to inform trade signal bias:
    - Trend: continuation trades preferred
    - Range: mean reversion / vol selling preferred
    - High Vol Event: volatility expansion trades preferred
    """
    
    def __init__(self):
        # Configuration
        self.trend_threshold_pct = 1.5  # >1.5% move = trending
        self.range_threshold_pct = 0.5  # <0.5% move = ranging
        self.high_vol_threshold_pct = 3.0  # >3% move = high vol event
        self.lookback_minutes = 60  # Lookback window for regime detection
    
    def detect_regime(
        self,
        df: pd.DataFrame,
        row_idx: int
    ) -> str:
        """
        Detect market regime for a given flow event.
        Returns MarketRegime enum value as string.
        """
        if row_idx >= len(df):
            return MarketRegime.RANGE.value
        
        current_row = df.iloc[row_idx]
        symbol = current_row.get('symbol_norm')
        flow_ts_utc = current_row.get('flow_ts_utc')
        
        if pd.isna(symbol) or pd.isna(flow_ts_utc):
            return MarketRegime.RANGE.value
        
        # Get price movement over lookback window
        pct_vs_rth_open = current_row.get('pct_vs_rth_open')
        pct_vs_prior_close = current_row.get('pct_vs_prior_close')
        pct_15m_momo = current_row.get('pct_15m_momo')
        
        # Use most appropriate price metric
        price_move_pct = None
        if pct_vs_rth_open is not None and not pd.isna(pct_vs_rth_open):
            price_move_pct = abs(pct_vs_rth_open)
        elif pct_vs_prior_close is not None and not pd.isna(pct_vs_prior_close):
            price_move_pct = abs(pct_vs_prior_close)
        elif pct_15m_momo is not None and not pd.isna(pct_15m_momo):
            price_move_pct = abs(pct_15m_momo)
        
        if price_move_pct is None:
            return MarketRegime.RANGE.value  # Default to range
        
        # Classify regime
        if price_move_pct >= self.high_vol_threshold_pct:
            return MarketRegime.HIGH_VOL_EVENT.value
        elif price_move_pct >= self.trend_threshold_pct:
            return MarketRegime.TREND.value
        elif price_move_pct <= self.range_threshold_pct:
            return MarketRegime.RANGE.value
        else:
            # Between range and trend threshold - classify based on momentum
            if pct_15m_momo is not None and not pd.isna(pct_15m_momo):
                if abs(pct_15m_momo) > 0.75:
                    return MarketRegime.TREND.value
            return MarketRegime.RANGE.value
    
    def enrich_with_market_regime(self, df: pd.DataFrame) -> pd.DataFrame:
        """
        Add market regime classification to DataFrame.
        Adds: market_regime
        """
        if df.empty:
            return df
        
        df = df.copy()
        df['market_regime'] = MarketRegime.RANGE.value
        
        # Detect regime for each row
        for idx in df.index:
            regime = self.detect_regime(df, idx)
            df.at[idx, 'market_regime'] = regime
        
        regime_counts = df['market_regime'].value_counts()
        logger.info(f"Market regime detection complete. Distribution: {regime_counts.to_dict()}")
        
        return df

