from dataclasses import dataclass
from typing import Dict, Tuple

@dataclass
class AnomalyResult:
    is_anomaly: bool
    side: str = ""
    severity: float = 0.0
    reason: str = ""

class OddsAnomalyDetector:
    """
    Detects mismatches between bookmaker odds and underlying team metrics.
    A 'Bookmaker Trap' is when a team has very low odds (heavy favorite)
    but their xG/defense metrics are surprisingly poor.
    """
    
    def __init__(self, config: Dict):
        self.config = config
        
        # Thresholds
        self.fav_odds_threshold = self.config.get("anomaly.fav_odds_threshold", 1.75)
        self.min_xg_for_fav = self.config.get("anomaly.min_xg_for_fav", 1.25)
        self.max_conceded_for_fav = self.config.get("anomaly.max_conceded_for_fav", 1.30)
        self.opp_min_xg_threat = self.config.get("anomaly.opp_min_xg_threat", 1.10)
        
    def detect_trap(self, 
                    odds_data: Dict[str, float], 
                    home_xg: float, 
                    away_xg: float, 
                    home_conceded_avg: float, 
                    away_conceded_avg: float) -> tuple[bool, AnomalyResult]:
        """
        Check if the match is a potential odds trap.
        Returns: (has_trap, AnomalyResult)
        """
        ms_h = odds_data.get("ms_h", 0.0)
        ms_a = odds_data.get("ms_a", 0.0)
        
        # Check Home Favorite Trap
        if 1.0 < ms_h <= self.fav_odds_threshold:
            # Home is favored. Check metrics.
            if home_xg < self.min_xg_for_fav and (away_xg > self.opp_min_xg_threat or home_conceded_avg > self.max_conceded_for_fav):
                severity = (self.fav_odds_threshold - ms_h) + (self.min_xg_for_fav - home_xg)
                reason = f"🚨 ODDS ANOMALY (TRAP): Home odds ({ms_h}) suspiciously low despite poor metrics (xG: {round(home_xg, 2)}, Conceded: {round(home_conceded_avg, 2)})"
                return True, AnomalyResult(True, "H", min(10.0, severity * 2), reason)

        # Check Away Favorite Trap
        if 1.0 < ms_a <= self.fav_odds_threshold:
            # Away is favored. Check metrics
            if away_xg < self.min_xg_for_fav and (home_xg > self.opp_min_xg_threat or away_conceded_avg > self.max_conceded_for_fav):
                severity = (self.fav_odds_threshold - ms_a) + (self.min_xg_for_fav - away_xg)
                reason = f"🚨 ODDS ANOMALY (TRAP): Away odds ({ms_a}) suspiciously low despite poor metrics (xG: {round(away_xg, 2)}, Conceded: {round(away_conceded_avg, 2)})"
                return True, AnomalyResult(True, "A", min(10.0, severity * 2), reason)
                
        return False, AnomalyResult(False)
