"""
Low Performance Filter

Blocks trading for factors/portfolios with consistently poor performance.
"""

from dataclasses import dataclass
from datetime import datetime
from .base import BaseProtection, ProtectionConfig, ProtectionResult, ProtectionType, ProtectionScope


@dataclass
class LowPerformanceConfig(ProtectionConfig):
    """Configuration for LowPerformance protection."""
    min_sharpe_ratio: float = 0.5  # Minimum acceptable Sharpe
    min_win_rate: float = 0.40  # Minimum 40% win rate
    min_trades: int = 20  # Need at least this many trades to evaluate


class LowPerformanceProtection(BaseProtection):
    """
    Filters out consistently underperforming factors.

    Prevents wasting resources on factors that statistical analysis
    shows are unlikely to become profitable.
    """

    def __init__(self, config: LowPerformanceConfig):
        super().__init__(config)
        self.config: LowPerformanceConfig = config

    @property
    def scope(self) -> ProtectionScope:
        return ProtectionScope.FACTOR

    def check(
        self,
        returns: list[float],
        timestamps: list[datetime],
        current_equity: float,
        peak_equity: float,
        **kwargs
    ) -> ProtectionResult:
        """Check if performance is below minimum standards."""
        self.record_check()

        if not self.config.enabled:
            return ProtectionResult(
                should_block=False,
                reason="Protection disabled",
                protection_type=ProtectionType.LOW_PERFORMANCE
            )

        # Need minimum number of trades
        if len(returns) < self.config.min_trades:
            return ProtectionResult(
                should_block=False,
                reason=f"Insufficient data ({len(returns)} < {self.config.min_trades} trades)",
                protection_type=ProtectionType.LOW_PERFORMANCE,
                severity=0.0
            )

        # Calculate metrics
        import numpy as np
        returns_array = np.array(returns)

        # Win rate
        wins = int(np.sum(returns_array > 0))
        win_rate = wins / len(returns)

        # Sharpe ratio (annualized, assuming daily returns)
        mean_return = float(np.mean(returns_array))
        std_return = float(np.std(returns_array))
        sharpe = (mean_return / std_return * np.sqrt(252)) if std_return > 0 else 0

        # Check thresholds
        reasons = []
        severity = 0.0

        if sharpe < self.config.min_sharpe_ratio:
            reasons.append(f"Sharpe {sharpe:.2f} < {self.config.min_sharpe_ratio}")
            severity = max(severity, (self.config.min_sharpe_ratio - sharpe) / self.config.min_sharpe_ratio)

        if win_rate < self.config.min_win_rate:
            reasons.append(f"Win rate {win_rate*100:.1f}% < {self.config.min_win_rate*100:.1f}%")
            severity = max(severity, (self.config.min_win_rate - win_rate) / self.config.min_win_rate)

        if reasons:
            result = ProtectionResult(
                should_block=True,
                reason=" | ".join(reasons),
                protection_type=ProtectionType.LOW_PERFORMANCE,
                severity=severity
            )
            self.record_check(blocked=True)
            return result

        return ProtectionResult(
            should_block=False,
            reason=f"Performance acceptable (Sharpe: {sharpe:.2f}, Win rate: {win_rate*100:.1f}%)",
            protection_type=ProtectionType.LOW_PERFORMANCE,
            severity=severity
        )
