"""Modèle User pour l'authentification et la gestion des utilisateurs."""

import uuid
from datetime import datetime
from typing import Optional

from sqlalchemy import String, Boolean, DateTime
from sqlalchemy.orm import Mapped, mapped_column, relationship
from flask_sqlalchemy import SQLAlchemy

db = SQLAlchemy()


class User(db.Model):
    """Modèle représentant un utilisateur de l'application.
    
    Attributes:
        id: Identifiant unique (UUID).
        email: Adresse email (unique).
        username: Nom d'utilisateur (unique).
        hashed_password: Mot de passe hashé avec bcrypt.
        is_active: Compte actif ou non.
        is_verified: Email vérifié ou non.
        verification_token: Token de vérification email.
        reset_token: Token de réinitialisation mot de passe.
        created_at: Date de création du compte.
        updated_at: Date de dernière mise à jour.
    """
    
    __tablename__ = 'users'
    
    # Primary Key
    id: Mapped[str] = mapped_column(
        String(36),
        primary_key=True,
        default=lambda: str(uuid.uuid4())
    )
    
    # Credentials
    email: Mapped[str] = mapped_column(
        String(255),
        unique=True,
        nullable=False,
        index=True
    )
    username: Mapped[str] = mapped_column(
        String(50),
        unique=True,
        nullable=False,
        index=True
    )
    hashed_password: Mapped[str] = mapped_column(
        String(255),
        nullable=False
    )
    
    # Account Status
    is_active: Mapped[bool] = mapped_column(
        Boolean,
        default=True,
        nullable=False
    )
    is_verified: Mapped[bool] = mapped_column(
        Boolean,
        default=False,
        nullable=False
    )
    is_admin: Mapped[bool] = mapped_column(
        Boolean,
        default=False,
        nullable=False
    )
    
    # Tokens
    verification_token: Mapped[Optional[str]] = mapped_column(
        String(255),
        nullable=True
    )
    reset_token: Mapped[Optional[str]] = mapped_column(
        String(255),
        nullable=True
    )
    
    # Timestamps
    created_at: Mapped[datetime] = mapped_column(
        DateTime,
        default=datetime.utcnow,
        nullable=False
    )
    updated_at: Mapped[datetime] = mapped_column(
        DateTime,
        default=datetime.utcnow,
        onupdate=datetime.utcnow,
        nullable=False
    )
    
    # Relationships
    stories: Mapped[list["Story"]] = relationship(
        "Story",
        back_populates="user",
        cascade="all, delete-orphan"
    )
    liked_stories: Mapped[list["StoryLike"]] = relationship(
        "StoryLike",
        back_populates="user",
        cascade="all, delete-orphan"
    )
    favorite_stories: Mapped[list["StoryFavorite"]] = relationship(
        "StoryFavorite",
        back_populates="user",
        cascade="all, delete-orphan"
    )
    
    def __repr__(self) -> str:
        """Représentation string du User."""
        return f"<User {self.username} ({self.email})>"
    
    def to_dict(self) -> dict:
        """Convertit le User en dictionnaire (sans le password).
        
        Returns:
            Dictionnaire avec les informations publiques de l'utilisateur.
        """
        return {
            'id': self.id,
            'email': self.email,
            'username': self.username,
            'is_active': self.is_active,
            'is_verified': self.is_verified,
            'is_admin': self.is_admin,
            'created_at': self.created_at.isoformat(),
            'updated_at': self.updated_at.isoformat()
        }

