"""Modèle StoryTurn pour les tours de jeu d'une histoire."""

import uuid
from datetime import datetime
from typing import Optional

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


class StoryTurn(db.Model):
    """Modèle représentant un tour de jeu dans une histoire.
    
    Un tour contient :
    - Le texte narratif généré par l'IA
    - L'action du joueur
    - Les choix proposés (si mode choix multiples)
    - Un flag indiquant si c'est un message technique (OFF)
    
    Attributes:
        id: Identifiant unique (UUID).
        story_id: ID de l'histoire.
        turn_number: Numéro du tour (séquentiel).
        narrative_text: Texte narratif généré par l'IA.
        player_action: Action du joueur (choix ou texte libre).
        action_type: Type d'action ('choice' ou 'free_text').
        is_technical: TRUE si message OFF (instruction technique).
        available_choices: Choix proposés si mode choices (JSON).
        selected_choice_index: Index du choix sélectionné.
        is_published: TRUE si passage fait partie de la version publique.
        tokens_used: Nombre de tokens utilisés pour ce tour.
        created_at: Date de création du tour.
    """
    
    __tablename__ = 'story_turns'
    
    # Primary Key
    id: Mapped[str] = mapped_column(
        String(36),
        primary_key=True,
        default=lambda: str(uuid.uuid4())
    )
    
    # Foreign Key
    story_id: Mapped[str] = mapped_column(
        String(36),
        ForeignKey('stories.id', ondelete='CASCADE'),
        nullable=False,
        index=True
    )
    
    # Turn Info
    turn_number: Mapped[int] = mapped_column(
        Integer,
        nullable=False
    )
    
    # Contenu narratif
    narrative_text: Mapped[str] = mapped_column(
        Text,
        nullable=False
    )
    
    # Action du joueur
    player_action: Mapped[Optional[str]] = mapped_column(
        Text,
        nullable=True
    )
    action_type: Mapped[Optional[str]] = mapped_column(
        String(20),
        nullable=True
    )
    is_technical: Mapped[bool] = mapped_column(
        Boolean,
        default=False,
        nullable=False,
        index=True
    )
    
    # Choix (si mode choices)
    available_choices: Mapped[Optional[list]] = mapped_column(
        JSON,
        nullable=True
    )
    selected_choice_index: Mapped[Optional[int]] = mapped_column(
        Integer,
        nullable=True
    )
    
    # Publication
    is_published: Mapped[bool] = mapped_column(
        Boolean,
        default=False,
        nullable=False,
        index=True
    )
    
    # Métadonnées
    tokens_used: Mapped[Optional[int]] = mapped_column(
        Integer,
        nullable=True
    )
    created_at: Mapped[datetime] = mapped_column(
        DateTime,
        default=datetime.utcnow,
        nullable=False
    )
    
    # Relationships
    story: Mapped["Story"] = relationship(
        "Story",
        back_populates="turns"
    )
    
    def __repr__(self) -> str:
        """Représentation string du StoryTurn."""
        return f"<StoryTurn #{self.turn_number} of Story {self.story_id}>"
    
    def to_dict(self) -> dict:
        """Convertit le StoryTurn en dictionnaire.
        
        Returns:
            Dictionnaire avec les informations du tour.
        """
        return {
            'id': self.id,
            'story_id': self.story_id,
            'turn_number': self.turn_number,
            'narrative_text': self.narrative_text,
            'player_action': self.player_action,
            'action_type': self.action_type,
            'is_technical': self.is_technical,
            'available_choices': self.available_choices,
            'selected_choice_index': self.selected_choice_index,
            'is_published': self.is_published,
            'tokens_used': self.tokens_used,
            'created_at': self.created_at.isoformat()
        }

