"""Collection model for Mantimon TCG.

This module defines the Collection model for tracking player card ownership.
Each entry represents a card the player owns, with quantity and source tracking.

Example:
    collection_entry = Collection(
        user_id=user.id,
        card_definition_id="pikachu_base_001",
        quantity=3,
        source=CardSource.BOOSTER
    )
"""

from datetime import UTC, datetime
from enum import Enum
from typing import TYPE_CHECKING
from uuid import UUID

from sqlalchemy import (
    DateTime,
    ForeignKey,
    Index,
    Integer,
    String,
    UniqueConstraint,
)
from sqlalchemy import (
    Enum as SQLEnum,
)
from sqlalchemy.orm import Mapped, mapped_column, relationship

from app.db.base import Base

if TYPE_CHECKING:
    from app.db.models.user import User


class CardSource(str, Enum):
    """Source of how a card was obtained.

    Attributes:
        STARTER: From a starter deck selection.
        BOOSTER: From opening a booster pack.
        REWARD: From winning matches or achievements.
        PURCHASE: From direct purchase with Mantibucks.
        TRADE: From trading with another player.
        GIFT: From promotional events or gifts.
    """

    STARTER = "starter"
    BOOSTER = "booster"
    REWARD = "reward"
    PURCHASE = "purchase"
    TRADE = "trade"
    GIFT = "gift"


class Collection(Base):
    """Player card collection entry.

    Tracks ownership of cards with quantity and source information.
    Each (user_id, card_definition_id) pair is unique - quantities are aggregated.

    Attributes:
        id: Unique identifier (UUID).
        user_id: Foreign key to the owning user.
        card_definition_id: ID of the card definition (e.g., "pikachu_base_001").
        quantity: Number of copies owned (1+).
        source: How the first copy was obtained.
        obtained_at: When the card was first added to collection.
        created_at: Record creation timestamp.
        updated_at: Record update timestamp.

    Relationships:
        user: The user who owns this card.
    """

    __tablename__ = "collections"

    # Ownership
    user_id: Mapped[UUID] = mapped_column(
        ForeignKey("users.id", ondelete="CASCADE"),
        nullable=False,
        index=True,
        doc="Foreign key to owning user",
    )

    # Card reference (string ID matching card JSON data)
    card_definition_id: Mapped[str] = mapped_column(
        String(100),
        nullable=False,
        doc="Card definition ID (e.g., 'pikachu_base_001')",
    )

    # Quantity tracking
    quantity: Mapped[int] = mapped_column(
        Integer,
        default=1,
        nullable=False,
        doc="Number of copies owned",
    )

    # Source tracking
    source: Mapped[CardSource] = mapped_column(
        SQLEnum(CardSource, name="card_source", create_constraint=True),
        nullable=False,
        doc="How the card was obtained",
    )

    # When first obtained
    obtained_at: Mapped[datetime] = mapped_column(
        DateTime(timezone=True),
        default=lambda: datetime.now(UTC),
        nullable=False,
        doc="When card was first added to collection",
    )

    # Relationship
    user: Mapped["User"] = relationship(
        "User",
        back_populates="collection",
    )

    # Constraints and indexes
    __table_args__ = (
        UniqueConstraint("user_id", "card_definition_id", name="uq_collection_user_card"),
        Index("ix_collection_card", "card_definition_id"),
    )

    def __repr__(self) -> str:
        return (
            f"<Collection(user_id={self.user_id!r}, "
            f"card={self.card_definition_id!r}, qty={self.quantity})>"
        )
