from __future__ import annotations

import logging
from dataclasses import dataclass, field

import numpy as np
import pandas as pd

from config.settings import settings

logger = logging.getLogger(__name__)


@dataclass
class MACDSignal:
    symbol: str
    action: str           # "BUY" | "SELL" | "HOLD"
    confidence: float     # 0.0 إلى 1.0
    source: str = "macd_bot"
    macd_value: float = 0.0
    signal_value: float = 0.0
    histogram: float = 0.0
    timeframe: str = "5m"

    def to_brain_payload(self) -> dict:
        """تنسيق الإرسال لـ Brain Bot."""
        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,
            "macd_value": round(self.macd_value, 8),
            "signal_value": round(self.signal_value, 8),
            "histogram": round(self.histogram, 8),
            "timeframe": self.timeframe,
            "sent_to_brain": sent_to_brain,
        }


class MACDSignalGenerator:
    """
    يُطبِّق قواعد MACD Crossover على آخر شمعتين.
    """

    def generate(
        self, symbol: str, macd_df: pd.DataFrame, timeframe: str
    ) -> MACDSignal:
        if len(macd_df) < 2:
            logger.warning(f"بيانات غير كافية لـ {symbol}: {len(macd_df)} صف")
            return MACDSignal(symbol=symbol, action="HOLD", confidence=0.0,
                              timeframe=timeframe)

        # آخر شمعتان
        macd_curr = float(macd_df["macd"].iloc[-1])
        macd_prev = float(macd_df["macd"].iloc[-2])
        sig_curr  = float(macd_df["signal"].iloc[-1])
        sig_prev  = float(macd_df["signal"].iloc[-2])
        hist_curr = float(macd_df["histogram"].iloc[-1])
        hist_prev = float(macd_df["histogram"].iloc[-2])

        # اكتشاف التقاطع
        bullish_cross = macd_prev <= sig_prev and macd_curr > sig_curr
        bearish_cross = macd_prev >= sig_prev and macd_curr < sig_curr

        if bullish_cross:
            action = "BUY"
        elif bearish_cross:
            action = "SELL"
        else:
            action = "HOLD"

        confidence = self._calculate_confidence(action, hist_curr, hist_prev, macd_df)

        sig = MACDSignal(
            symbol=symbol,
            action=action,
            confidence=confidence,
            timeframe=timeframe,
            macd_value=macd_curr,
            signal_value=sig_curr,
            histogram=hist_curr,
        )

        logger.info(
            f"إشارة MACD: {action} {symbol} ({timeframe}) "
            f"ثقة={confidence:.2f} "
            f"macd={macd_curr:.6f} signal={sig_curr:.6f} hist={hist_curr:.6f}"
        )
        return sig

    def _calculate_confidence(
        self,
        action: str,
        histogram_curr: float,
        histogram_prev: float,
        macd_df: pd.DataFrame,
    ) -> float:
        if action == "HOLD":
            return 0.0

        # قوة التقاطع = التغيير في الـ histogram
        crossover_strength = abs(histogram_curr - histogram_prev)

        # عتبة نسبية: متوسط قيم الـ histogram المطلقة في آخر 5 شمعات
        recent_hist = macd_df["histogram"].iloc[-5:].abs()
        avg_hist = float(recent_hist.mean()) if len(recent_hist) > 0 else 1e-9

        if avg_hist == 0:
            return settings.CONFIDENCE_WEAK

        relative_strength = crossover_strength / avg_hist

        if relative_strength >= 1.0:
            return settings.CONFIDENCE_STRONG
        else:
            # تدرج بين WEAK و STRONG
            ratio = min(relative_strength, 1.0)
            confidence = settings.CONFIDENCE_WEAK + ratio * (
                settings.CONFIDENCE_STRONG - settings.CONFIDENCE_WEAK
            )
            return round(confidence, 4)


signal_generator = MACDSignalGenerator()
