"""Service pour la gestion automatique du LoreBook."""

import json
from typing import Optional, Dict
from openai import OpenAI

from config import Config
from models.lorebook import LoreBook
from models.story_turn import StoryTurn
from models.user import db


class LoreBookService:
    """Service pour mettre à jour automatiquement le LoreBook."""
    
    @staticmethod
    def _get_client() -> OpenAI:
        """Obtient une instance du client OpenAI.
        
        Returns:
            Client OpenAI configuré.
        """
        return OpenAI(api_key=Config.OPENAI_API_KEY)
    
    @staticmethod
    def should_update_lorebook(
        narrative_text: str,
        player_action: Optional[str] = None
    ) -> bool:
        """Détermine si le LoreBook doit être mis à jour.
        
        Critères simples pour l'instant :
        - Toujours mettre à jour pour avoir un LoreBook riche
        
        Args:
            narrative_text: Texte narratif du passage.
            player_action: Action du joueur.
        
        Returns:
            True si mise à jour nécessaire.
        """
        # Pour l'instant, on met à jour à chaque tour pour avoir un LoreBook riche
        # On pourrait optimiser plus tard en détectant les passages "importants"
        return True
    
    @staticmethod
    def update_lorebook(
        lorebook: LoreBook,
        narrative_text: str,
        player_action: Optional[str] = None,
        turn_number: int = 0
    ) -> LoreBook:
        """Met à jour le LoreBook avec les nouvelles informations.
        
        Args:
            lorebook: LoreBook actuel.
            narrative_text: Nouveau passage narratif.
            player_action: Action du joueur.
            turn_number: Numéro du tour actuel.
        
        Returns:
            LoreBook mis à jour.
        """
        current_lorebook_str = json.dumps({
            "personnages": lorebook.characters or [],
            "lieux": lorebook.locations or [],
            "objets": lorebook.items or [],
            "evenements_cles": lorebook.key_events or [],
            "etat_protagoniste": lorebook.protagonist_state or {}
        }, ensure_ascii=False, indent=2)
        
        prompt = f"""Analyse le dernier passage narratif et l'action du joueur pour mettre à jour le LoreBook.

## Passage narratif
{narrative_text}

## Action du joueur
{player_action if player_action else "Aucune (premier passage)"}

## LoreBook actuel
{current_lorebook_str}

## Instructions
Analyse le passage et détermine s'il y a des éléments importants à ajouter ou mettre à jour :
- Nouveau personnage significatif ?
- Nouveau lieu important ?
- Objet clé obtenu/perdu ?
- Événement majeur ?
- Évolution du protagoniste (nouveaux traits, compétences, blessures) ?

Si OUI, retourne le LoreBook mis à jour en JSON.
Si NON (pas d'éléments importants), retourne {{"update_needed": false}}

Format JSON attendu (si mise à jour nécessaire) :
{{
  "update_needed": true,
  "characters": [
    {{"name": "Nom", "description": "Description", "traits": ["trait1", "trait2"], "relation": "Relation avec le protagoniste"}}
  ],
  "locations": [
    {{"name": "Nom", "description": "Description", "importance": "Pourquoi c'est important"}}
  ],
  "items": [
    {{"name": "Nom", "description": "Description", "status": "possédé/perdu/vu"}}
  ],
  "key_events": [
    "Événement important 1",
    "Événement important 2"
  ],
  "protagonist_state": {{
    "traits": ["trait1", "trait2"],
    "skills": ["compétence1"],
    "conditions": ["blessure", "état"],
    "possessions": ["objet1", "objet2"]
  }}
}}

Retourne UNIQUEMENT le JSON, sans texte additionnel."""

        try:
            client = LoreBookService._get_client()
            response = client.chat.completions.create(
                model=Config.OPENAI_MODEL_CHAT,
                messages=[
                    {"role": "system", "content": "Tu es un assistant qui met à jour des LoreBooks pour des histoires interactives. Tu réponds toujours en JSON valide."},
                    {"role": "user", "content": prompt}
                ],
                temperature=0.3,  # Plus déterministe pour la mise à jour
                max_tokens=800
            )
            
            content = response.choices[0].message.content.strip()
            
            # Extraire le JSON
            if "```json" in content:
                content = content.split("```json")[1].split("```")[0].strip()
            elif "```" in content:
                content = content.split("```")[1].split("```")[0].strip()
            
            data = json.loads(content)
            
            # Vérifier si une mise à jour est nécessaire
            if not data.get("update_needed", True):
                return lorebook
            
            # Mettre à jour le LoreBook
            if "characters" in data:
                # Fusionner avec les personnages existants
                existing_chars = {c.get("name"): c for c in (lorebook.characters or [])}
                for char in data["characters"]:
                    existing_chars[char.get("name")] = char
                lorebook.characters = list(existing_chars.values())
            
            if "locations" in data:
                existing_locs = {loc.get("name"): loc for loc in (lorebook.locations or [])}
                for loc in data["locations"]:
                    existing_locs[loc.get("name")] = loc
                lorebook.locations = list(existing_locs.values())
            
            if "items" in data:
                existing_items = {item.get("name"): item for item in (lorebook.items or [])}
                for item in data["items"]:
                    existing_items[item.get("name")] = item
                lorebook.items = list(existing_items.values())
            
            if "key_events" in data:
                # Ajouter les nouveaux événements
                existing_events = lorebook.key_events or []
                new_events = [e for e in data["key_events"] if e not in existing_events]
                lorebook.key_events = existing_events + new_events
            
            if "protagonist_state" in data:
                # Mettre à jour l'état du protagoniste
                lorebook.protagonist_state = data["protagonist_state"]
            
            # Mettre à jour les métadonnées
            lorebook.last_updated_turn = turn_number
            lorebook.version += 1
            
            db.session.commit()
            
            return lorebook
            
        except json.JSONDecodeError as e:
            # En cas d'erreur, on ne met pas à jour
            return lorebook
            
        except Exception as e:
            # En cas d'erreur, on ne met pas à jour
            return lorebook

