"""
Modèles de données SQLAlchemy pour Versailles Airsoft.
Comprend les entités User, Availability et Game.
"""

from datetime import datetime
from sqlalchemy import (
    Column,
    Integer,
    String,
    Date,
    DateTime,
    Boolean,
    ForeignKey,
    UniqueConstraint
)
from sqlalchemy.orm import relationship
from database import Base

# Créneaux horaires autorisés
VALID_SLOTS = [
    "Matin (09h-13h)",
    "Après-midi (13h-17h)"
]


class User(Base):
    """Modèle utilisateur / joueur d'airsoft."""
    __tablename__ = "users"

    id = Column(Integer, primary_key=True, index=True)
    username = Column(String(50), unique=True, index=True, nullable=False)
    hashed_password = Column(String(255), nullable=False)
    created_at = Column(DateTime, default=datetime.utcnow, nullable=False)

    # Relations
    availabilities = relationship(
        "Availability",
        back_populates="user",
        cascade="all, delete-orphan",
        order_by="Availability.date"
    )

    def __repr__(self):
        return f"<User(id={self.id}, username='{self.username}')>"


class Availability(Base):
    """Modèle de disponibilité d'un joueur pour une date et un créneau."""
    __tablename__ = "availabilities"

    id = Column(Integer, primary_key=True, index=True)
    user_id = Column(Integer, ForeignKey("users.id", ondelete="CASCADE"), nullable=False, index=True)
    date = Column(Date, nullable=False, index=True)
    slot = Column(String(50), nullable=False)
    created_at = Column(DateTime, default=datetime.utcnow, nullable=False)

    # Relations
    user = relationship("User", back_populates="availabilities")

    # Contrainte unique par utilisateur, date et créneau
    __table_args__ = (
        UniqueConstraint("user_id", "date", "slot", name="uq_user_date_slot"),
    )

    def __repr__(self):
        return f"<Availability(user_id={self.user_id}, date={self.date}, slot='{self.slot}')>"


class Game(Base):
    """
    Modèle de partie validée (automatiquement créée quand le seuil de 8 joueurs est atteint).
    """
    __tablename__ = "games"

    id = Column(Integer, primary_key=True, index=True)
    date = Column(Date, nullable=False, index=True)
    slot = Column(String(50), nullable=False)
    player_count = Column(Integer, default=0, nullable=False)
    notified_discord = Column(Boolean, default=False, nullable=False)
    created_at = Column(DateTime, default=datetime.utcnow, nullable=False)

    # Contrainte unique par date et créneau
    __table_args__ = (
        UniqueConstraint("date", "slot", name="uq_game_date_slot"),
    )

    def __repr__(self):
        return f"<Game(id={self.id}, date={self.date}, slot='{self.slot}', count={self.player_count})>"
