"""Multi-model consensus evaluator."""

import hashlib
from typing import Dict, Any
import time

from .base import BaseEvaluator
from ..models import get_model


class MultiModelEvaluator(BaseEvaluator):
    """Evaluates content using multiple models and computes consensus."""
    
    def __init__(self, config):
        super().__init__(config)
        self.models = [get_model(m) for m in config.models]
    
    def evaluate(self, item: Dict[str, Any]) -> Dict[str, Any]:
        """Evaluate item with all configured models."""
        content = item.get("content", "")
        content_hash = hashlib.sha256(content.encode()).hexdigest()[:8]
        
        decisions = {}
        
        for model, model_cfg in zip(self.models, self.config.models):
            model_id = f"{model_cfg.provider}/{model_cfg.model}"
            
            start_time = time.time()
            try:
                decision = model.evaluate(content)
                latency_ms = (time.time() - start_time) * 1000
                
                decisions[model_id] = {
                    "decision": decision["decision"],
                    "confidence": decision.get("confidence", 0.5),
                    "latency_ms": latency_ms,
                }
            except Exception as e:
                decisions[model_id] = {
                    "decision": False,
                    "confidence": 0.0,
                    "latency_ms": 0.0,
                    "error": str(e),
                }
        
        # Compute weighted consensus
        total_weight = sum(cfg.weight for cfg in self.config.models)
        weighted_votes = sum(
            cfg.weight for cfg, d in zip(self.config.models, decisions.values())
            if d.get("decision", False)
        )
        
        consensus = weighted_votes > total_weight / 2
        
        # Compute agreement (fraction agreeing with consensus)
        decision_values = [d["decision"] for d in decisions.values()]
        agreement = sum(1 for d in decision_values if d == consensus) / len(decision_values) if decision_values else 0.0
        
        return {
            "item_id": item.get("id", "unknown"),
            "content_hash": content_hash,
            "category": item.get("category", "unknown"),
            "decisions": decisions,
            "consensus": consensus,
            "agreement": agreement,
            "weighted_score": weighted_votes / total_weight,
        }
