"""Modèle LoreBook pour mémoriser les éléments clés d'une histoire."""

import uuid
from datetime import datetime
from typing import Optional

from sqlalchemy import String, Integer, DateTime, ForeignKey, JSON
from sqlalchemy.orm import Mapped, mapped_column, relationship
from models.user import db


class LoreBook(db.Model):
    """Modèle représentant le LoreBook d'une histoire.
    
    Le LoreBook contient une synthèse des éléments importants :
    - Personnages rencontrés
    - Lieux visités
    - Objets clés obtenus
    - Événements majeurs
    - État du protagoniste
    
    Attributes:
        id: Identifiant unique (UUID).
        story_id: ID de l'histoire (unique).
        characters: Liste des personnages (JSON).
        locations: Liste des lieux (JSON).
        items: Liste des objets clés (JSON).
        key_events: Liste des événements majeurs (JSON).
        protagonist_state: État du protagoniste (JSON).
        last_updated_turn: Numéro du dernier tour de mise à jour.
        version: Version du LoreBook (incrémenté à chaque update).
        updated_at: Date de dernière mise à jour.
    """
    
    __tablename__ = 'lorebooks'
    
    # Primary Key
    id: Mapped[str] = mapped_column(
        String(36),
        primary_key=True,
        default=lambda: str(uuid.uuid4())
    )
    
    # Foreign Key (unique)
    story_id: Mapped[str] = mapped_column(
        String(36),
        ForeignKey('stories.id', ondelete='CASCADE'),
        unique=True,
        nullable=False,
        index=True
    )
    
    # Contenu structuré (JSON)
    characters: Mapped[Optional[list]] = mapped_column(
        JSON,
        nullable=True,
        default=list
    )
    locations: Mapped[Optional[list]] = mapped_column(
        JSON,
        nullable=True,
        default=list
    )
    items: Mapped[Optional[list]] = mapped_column(
        JSON,
        nullable=True,
        default=list
    )
    key_events: Mapped[Optional[list]] = mapped_column(
        JSON,
        nullable=True,
        default=list
    )
    protagonist_state: Mapped[Optional[dict]] = mapped_column(
        JSON,
        nullable=True,
        default=dict
    )
    
    # Métadonnées
    last_updated_turn: Mapped[int] = mapped_column(
        Integer,
        default=0,
        nullable=False
    )
    version: Mapped[int] = mapped_column(
        Integer,
        default=1,
        nullable=False
    )
    updated_at: Mapped[datetime] = mapped_column(
        DateTime,
        default=datetime.utcnow,
        onupdate=datetime.utcnow,
        nullable=False
    )
    
    # Relationships
    story: Mapped["Story"] = relationship(
        "Story",
        back_populates="lorebook"
    )
    
    def __repr__(self) -> str:
        """Représentation string du LoreBook."""
        return f"<LoreBook of Story {self.story_id} (v{self.version})>"
    
    def to_dict(self) -> dict:
        """Convertit le LoreBook en dictionnaire.
        
        Returns:
            Dictionnaire avec le contenu du LoreBook.
        """
        return {
            'id': self.id,
            'story_id': self.story_id,
            'characters': self.characters or [],
            'locations': self.locations or [],
            'items': self.items or [],
            'key_events': self.key_events or [],
            'protagonist_state': self.protagonist_state or {},
            'last_updated_turn': self.last_updated_turn,
            'version': self.version,
            'updated_at': self.updated_at.isoformat()
        }

