"""
Referee Predictor Engine - V20 Ensemble Component
Analyzes referee patterns for cards, goals, and home bias.

Weight: 15% in ensemble
"""

import os
import sys
from typing import Dict, Optional
from dataclasses import dataclass

sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))))

from features.referee_engine import get_referee_engine


@dataclass
class RefereePrediction:
    """Referee engine prediction output."""
    referee_name: str = ""
    matches_officiated: int = 0
    
    # Card tendencies
    avg_yellow_cards: float = 4.0
    avg_red_cards: float = 0.2
    is_card_heavy: bool = False  # Above average cards
    
    # Goal tendencies
    avg_goals_per_match: float = 2.5
    over_25_rate: float = 0.50
    is_high_scoring: bool = False  # Above average goals
    
    # Home bias
    home_win_rate: float = 0.45
    home_bias: float = 0.0  # -1 to +1, positive = favors home
    
    # Penalty tendency
    penalty_rate: float = 0.15
    
    confidence: float = 0.0
    
    def to_dict(self) -> dict:
        return {
            "referee_name": self.referee_name,
            "matches_officiated": self.matches_officiated,
            "avg_yellow_cards": round(self.avg_yellow_cards, 1),
            "avg_red_cards": round(self.avg_red_cards, 2),
            "is_card_heavy": self.is_card_heavy,
            "avg_goals_per_match": round(self.avg_goals_per_match, 2),
            "over_25_rate": round(self.over_25_rate * 100, 1),
            "is_high_scoring": self.is_high_scoring,
            "home_win_rate": round(self.home_win_rate * 100, 1),
            "home_bias": round(self.home_bias, 2),
            "penalty_rate": round(self.penalty_rate * 100, 1),
            "confidence": round(self.confidence, 1)
        }


class RefereePredictorEngine:
    """
    Referee-based prediction engine.
    
    Analyzes:
    - Card tendency (sarı/kırmızı kart ortalaması)
    - Goal tendency (maç başına gol, 2.5 üst oranı)
    - Home bias (ev sahibi lehine karar oranı)
    - Penalty tendency (penaltı verme oranı)
    """
    
    # League average benchmarks
    LEAGUE_AVG_GOALS = 2.65
    LEAGUE_AVG_YELLOW = 4.0
    LEAGUE_HOME_WIN_RATE = 0.45
    
    def __init__(self):
        self.referee_engine = get_referee_engine()
        print("✅ RefereePredictorEngine initialized")
    
    def predict(self,
                match_id: str = None,
                referee_name: str = None,
                league_id: str = None) -> RefereePrediction:
        """
        Generate referee-based prediction.
        
        Args:
            match_id: Match ID to find referee
            referee_name: Or provide referee name directly
            league_id: League ID to scope stats (prevents name collisions)
            
        Returns:
            RefereePrediction with referee analysis
        """
        
        # Get referee features
        if match_id:
            features = self.referee_engine.get_features(match_id, league_id=league_id)
            # Live flows may already have referee_name while match_officials table is sparse.
            # Prefer the richer profile if direct-name lookup has more history.
            if referee_name:
                name_features = self.referee_engine.get_features_by_name(referee_name, league_id=league_id)
                if (name_features.get("referee_matches", 0) or 0) > (features.get("referee_matches", 0) or 0):
                    features = name_features
        elif referee_name:
            features = self.referee_engine.get_features_by_name(referee_name, league_id=league_id)
        else:
            # Return default
            return RefereePrediction(confidence=10.0)
        
        ref_name = features.get("referee_name", "Unknown")
        matches = features.get("referee_matches", 0)
        
        if matches < 5:
            # Not enough data
            return RefereePrediction(
                referee_name=ref_name,
                matches_officiated=matches,
                confidence=20.0
            )
        
        # Extract features
        avg_yellow = features.get("referee_avg_yellow", 4.0)
        avg_red = features.get("referee_avg_red", 0.2)
        avg_goals = features.get("referee_avg_goals", 2.5)
        over25_rate = features.get("referee_over25_rate", 0.5)
        home_win_rate = features.get("referee_home_win_rate", 0.45) if "referee_home_win_rate" in features else 0.45
        home_bias = features.get("referee_home_bias", 0.0)
        penalty_rate = features.get("referee_penalty_rate", 0.15)
        
        # Determine tendencies
        is_card_heavy = (avg_yellow + avg_red * 4) > (self.LEAGUE_AVG_YELLOW + 1)
        is_high_scoring = avg_goals > self.LEAGUE_AVG_GOALS
        
        # Confidence based on matches officiated
        confidence = min(90.0, 30.0 + matches * 2)
        
        return RefereePrediction(
            referee_name=ref_name,
            matches_officiated=matches,
            avg_yellow_cards=avg_yellow,
            avg_red_cards=avg_red,
            is_card_heavy=is_card_heavy,
            avg_goals_per_match=avg_goals,
            over_25_rate=over25_rate,
            is_high_scoring=is_high_scoring,
            home_win_rate=home_win_rate,
            home_bias=home_bias,
            penalty_rate=penalty_rate,
            confidence=confidence
        )
    
    def get_modifiers(self, prediction: RefereePrediction) -> Dict[str, float]:
        """
        Get modifiers to apply to other predictions based on referee profile.
        """
        return {
            # Home team gets slight boost if referee has home bias
            "home_modifier": 1.0 + (prediction.home_bias * 0.05),
            # O/U modifier
            "over_25_modifier": 1.0 + (prediction.avg_goals_per_match - self.LEAGUE_AVG_GOALS) * 0.1,
            # Card modifier for card markets
            "cards_modifier": 1.0 + (prediction.avg_yellow_cards - self.LEAGUE_AVG_YELLOW) * 0.05
        }


# Singleton
_engine: Optional[RefereePredictorEngine] = None


def get_referee_predictor() -> RefereePredictorEngine:
    global _engine
    if _engine is None:
        _engine = RefereePredictorEngine()
    return _engine


if __name__ == "__main__":
    engine = get_referee_predictor()
    
    print("\n🧪 Referee Predictor Engine Test")
    print("=" * 50)
    
    pred = engine.predict(referee_name="Cüneyt Çakır")
    
    print(f"\n📊 Prediction:")
    for k, v in pred.to_dict().items():
        print(f"   {k}: {v}")
