from abc import ABC, abstractmethod
from typing import List, Dict, Any, Optional
from .utils.agent_config import AgentConfig

class BaseAgent(ABC):
    """
    Classe de base pour les agents.
    """
    def __init__(self, nom: str, llm: Any, role: Optional[str] = None):
        self.nom = nom
        self.llm = llm
        self.historique: List[Dict[str, Any]] = []
        
        # Détecter le type de modèle
        model_type = self._detecter_model_type()
        
        # Définir le rôle par défaut si non spécifié
        agent_role = role if role is not None else nom.lower().replace("agent", "").strip()
        
        # Créer la configuration d'agent
        self.config = AgentConfig(agent_role, model_type)
        
        # Appliquer les paramètres au LLM
        self._appliquer_config()
        
    def _detecter_model_type(self) -> str:
        """
        Détecte le type de modèle LLM.
        """
        llm_class_name = self.llm.__class__.__name__.lower()
        if "mistral" in llm_class_name:
            return "mistral"
        elif "pixtral" in llm_class_name:
            return "pixtral"
        elif "ollama" in llm_class_name:
            return "ollama"
        else:
            return "generic"
    
    def _appliquer_config(self) -> None:
        """
        Applique la configuration au modèle LLM.
        """
        # Appliquer le prompt système
        if hasattr(self.llm, "prompt_system"):
            self.llm.prompt_system = self.config.get_system_prompt()
        
        # Appliquer les paramètres
        if hasattr(self.llm, "configurer"):
            self.llm.configurer(**self.config.get_params())
        
    def ajouter_historique(self, action: str, input_data: Any, output_data: Any):
        # Ajouter les informations sur le modèle et les paramètres utilisés
        metadata = {
            "model": getattr(self.llm, "modele", str(type(self.llm))),
            "configuration": self.config.to_dict(),
            "duree_traitement": str(getattr(self.llm, "dureeTraitement", "N/A"))
        }
        
        self.historique.append({
            "action": action,
            "input": input_data,
            "output": output_data,
            "metadata": metadata
        })
    
    @abstractmethod
    def executer(self, *args, **kwargs) -> Any:
        pass
