import json
from typing import Dict, List, Any, Optional, Union
from .llm import LLM

class Perplexity(LLM):
    """
    Classe pour l'intégration avec l'API Perplexity
    Cette classe hérite de la classe de base LLM
    """
    
    def __init__(self):
        """
        Initialisation des attributs spécifiques à Perplexity
        """
        super().__init__()
        
        # Attributs spécifiques à Perplexity
        self.maxToken: int = 1000
        self.presence_penalty: int = 0
        self.frequency_penaly: int = 1  # Note: typo dans le code source - penaly au lieu de penalty
        self.search_recency_filter: str = "all"
        self.search_domain_filter: List[str] = []
        
        # Initialisation par défaut
        self.maxToken = 1000
        self.o_temperature = 0.5
        self.o_top_p = 0.8
        self.o_top_k = 0
        self.presence_penalty = 0
        self.frequency_penaly = 1
        self.search_recency_filter = "all"  # "year" est une autre option
        self.prompt_system = "Soyez précis et concis. Répondez uniquement en français. Effectuez une recherche approfondie et fournissez des informations détaillées et à jour."
    
    def cleAPI(self) -> str:
        """
        Retourne la clé API Perplexity
        """
        return "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"
    
    def urlBase(self) -> str:
        """
        Retourne l'URL de base de l'API Perplexity
        """
        return "https://api.perplexity.ai/chat/completions"
    
    def Interroger(self, question: str) -> str:
        """
        Interroge Perplexity avec une question
        Définit le modèle par défaut à "sonar"
        """
        self.Modele = "sonar"
        return self.LLM_POST(question)
    
    def _even_LLM_POST(self, question: str) -> None:
        """
        Préparation du contenu de la requête pour Perplexity
        """
        self._Contenu["messages"] = [
            {"role": "system", "content": self.prompt_system},
            {"role": "user", "content": question}
        ]
        
        # Ajout du nombre maximal de tokens si défini
        if self.maxToken != 0:
            self._Contenu["max_tokens"] = self.maxToken
        
        # Température et format
        self._Contenu["temperature"] = self.o_temperature
        if self.format:
            self._Contenu["response_format"] = self.format
        
        # Paramètres de filtrage
        self._Contenu["top_p"] = self.o_top_p
        
        # Ajout des domaines de recherche si définis
        if len(self.search_domain_filter) > 0:
            # Exemple de filtrage: ["perplexity.ai"]
            self._Contenu["search_domain_filter"] = self.search_domain_filter
        
        # Options supplémentaires
        self._Contenu["return_images"] = False
        self._Contenu["return_related_questions"] = False
        
        # Filtre de récence si autre que "all"
        if self.search_recency_filter != "all":
            self._Contenu["search_recency_filter"] = self.search_recency_filter
        
        # Autres paramètres
        self._Contenu["top_k"] = self.o_top_k
        self._Contenu["presence_penalty"] = self.presence_penalty
        self._Contenu["frequency_penalty"] = self.frequency_penaly
        self._Contenu["response_format"] = None  # Null en WLangage
    
    def _interrogerRetourneReponse(self, reponse: str) -> str:
        """
        Extraction de la réponse à partir du JSON retourné par Perplexity
        """
        data = json.loads(reponse)
        return data["choices"][0]["message"]["content"] 