from __future__ import annotations

import logging
from dataclasses import dataclass

import pandas as pd

from config.settings import settings

logger = logging.getLogger(__name__)


@dataclass
class RSISignal:
    symbol: str
    action: str        # "BUY" | "SELL" | "HOLD"
    confidence: float
    rsi_value: float
    source: str = "rsi_bot"
    timeframe: str = "5m"

    def to_brain_payload(self) -> dict:
        return {
            "symbol": self.symbol,
            "action": self.action,
            "confidence": self.confidence,
            "source": self.source,
        }

    def to_response_dict(self, sent_to_brain: bool) -> dict:
        return {
            "symbol": self.symbol,
            "action": self.action,
            "confidence": round(self.confidence, 4),
            "source": self.source,
            "rsi_value": round(self.rsi_value, 4),
            "timeframe": self.timeframe,
            "sent_to_brain": sent_to_brain,
        }


class RSISignalGenerator:
    """
    يُطبِّق قواعد RSI على آخر قيمة:
      RSI < 30  → BUY
      RSI > 70  → SELL
      30-70     → HOLD
    """

    def generate(
        self, symbol: str, rsi_series: pd.Series, timeframe: str
    ) -> RSISignal:
        # تجاهل NaN في البداية وأخذ آخر قيمة صالحة
        valid = rsi_series.dropna()
        if valid.empty:
            logger.warning(f"RSI لـ {symbol}: لا توجد قيم صالحة")
            return RSISignal(symbol=symbol, action="HOLD", confidence=0.0,
                             rsi_value=float("nan"), timeframe=timeframe)

        rsi_val = float(valid.iloc[-1])

        if rsi_val < settings.RSI_OVERSOLD:
            action = "BUY"
        elif rsi_val > settings.RSI_OVERBOUGHT:
            action = "SELL"
        else:
            action = "HOLD"

        confidence = self._calculate_confidence(action, rsi_val)

        sig = RSISignal(
            symbol=symbol,
            action=action,
            confidence=confidence,
            rsi_value=rsi_val,
            timeframe=timeframe,
        )

        logger.info(
            f"إشارة RSI: {action} {symbol} ({timeframe}) "
            f"RSI={rsi_val:.2f} ثقة={confidence:.2f}"
        )
        return sig

    def _calculate_confidence(self, action: str, rsi_val: float) -> float:
        if action == "HOLD":
            return 0.0

        if action == "BUY":
            if rsi_val <= settings.RSI_EXTREME_LOW:
                # RSI أقصى (0-20): تدرج من EXTREME_MIN إلى EXTREME_MAX
                # كلما انخفض RSI زادت الثقة
                ratio = (settings.RSI_EXTREME_LOW - rsi_val) / settings.RSI_EXTREME_LOW
                ratio = min(ratio, 1.0)
                conf = settings.CONFIDENCE_EXTREME_MIN + ratio * (
                    settings.CONFIDENCE_EXTREME_MAX - settings.CONFIDENCE_EXTREME_MIN
                )
            else:
                # RSI عادي (20-30): تدرج من NORMAL_MIN إلى NORMAL_MAX
                ratio = (settings.RSI_OVERSOLD - rsi_val) / (
                    settings.RSI_OVERSOLD - settings.RSI_EXTREME_LOW
                )
                ratio = max(0.0, min(ratio, 1.0))
                conf = settings.CONFIDENCE_NORMAL_MIN + ratio * (
                    settings.CONFIDENCE_NORMAL_MAX - settings.CONFIDENCE_NORMAL_MIN
                )
        else:  # SELL
            if rsi_val >= settings.RSI_EXTREME_HIGH:
                ratio = (rsi_val - settings.RSI_EXTREME_HIGH) / (100.0 - settings.RSI_EXTREME_HIGH)
                ratio = min(ratio, 1.0)
                conf = settings.CONFIDENCE_EXTREME_MIN + ratio * (
                    settings.CONFIDENCE_EXTREME_MAX - settings.CONFIDENCE_EXTREME_MIN
                )
            else:
                ratio = (rsi_val - settings.RSI_OVERBOUGHT) / (
                    settings.RSI_EXTREME_HIGH - settings.RSI_OVERBOUGHT
                )
                ratio = max(0.0, min(ratio, 1.0))
                conf = settings.CONFIDENCE_NORMAL_MIN + ratio * (
                    settings.CONFIDENCE_NORMAL_MAX - settings.CONFIDENCE_NORMAL_MIN
                )

        return round(conf, 4)


signal_generator = RSISignalGenerator()
