"""
SQLAlchemy ORM models for card mirrors and deck-card links.

Mirrored card data lives in mtgo_platform for fast deckbuilding queries.
The MTGJSON database remains the canonical source of truth.
"""
from sqlalchemy import (
    Column, Integer, String, Text, DateTime, ForeignKey, Index,
    UniqueConstraint, Boolean
)
from sqlalchemy.orm import relationship
from sqlalchemy.sql import func
from app.core.database import Base


class MtgCardMirror(Base):
    """
    Mirrored card data for user decks.

    Contains all relevant card fields copied from mtg_cards (mtg_data)
    to avoid cross-DB joins during deckbuilding. Back-references source_id
    to the canonical mtg_cards.id for sync tracking.
    """
    __tablename__ = "mtg_cards_mirror"

    id = Column(Integer, primary_key=True, index=True)
    source_id = Column(
        Integer, 
        nullable=True, 
        index=True,
        comment="Logical reference to mtg_cards.id in mtg_data database (cross-DB reference, no FK constraint)"
    )
    name = Column(String(255), nullable=False, index=True)
    mana_cost = Column(String(255), nullable=True)
    type_line = Column(String(255), nullable=True)
    oracle_text = Column(Text, nullable=True)
    power = Column(String(50), nullable=True)
    toughness = Column(String(50), nullable=True)
    rarity = Column(String(50), nullable=True)
    layout = Column(String(50), nullable=True)
    artist = Column(String(255), nullable=True)
    flavor_text = Column(Text, nullable=True)
    numbers = Column(String(100), nullable=True)
    identifiers = Column(Text, nullable=True)  # JSON string of all identifiers
    images = Column(Text, nullable=True)  # JSON string of image URLs
    image = Column(Text, nullable=True)  # Card image URL from MTGJSON
    card_parts = Column(Text, nullable=True)  # Comma-separated list of face names
    keywords = Column(Text, nullable=True)  # Comma-separated keywords
    legalities = Column(Text, nullable=True)  # JSON of format legality
    set_code = Column(String(10), nullable=True, index=True)
    set_name = Column(String(255), nullable=True)
    # Sync tracking
    synced_at = Column(DateTime, server_default=func.now(), onupdate=func.now())
    created_at = Column(DateTime, server_default=func.now())

    # Relationships
    deck_links = relationship(
        "DeckCardLink",
        back_populates="card",
        cascade="all, delete-orphan"
    )

    def __repr__(self) -> str:
        return f"<MtgCardMirror {self.name} (ID: {self.id}, source: {self.source_id})>"


class DeckCardLink(Base):
    """
    Junction table linking user decks to mirrored cards.

    Represents a specific quantity of a mirrored card in a specific zone
    (main deck or sideboard) of a user's deck.
    """
    __tablename__ = "deck_card_links"

    id = Column(Integer, primary_key=True, index=True)
    deck_id = Column(Integer, ForeignKey("mtgonline_decklist_files.id", ondelete="CASCADE"), nullable=False)
    card_id = Column(Integer, ForeignKey("mtg_cards_mirror.id"), nullable=False)
    quantity = Column(Integer, nullable=False, default=1)
    zone = Column(String(20), nullable=False, default="main")  # 'main' or 'sideboard'

    # Composite unique: a card can only appear once per zone in a deck
    __table_args__ = (
        UniqueConstraint('deck_id', 'card_id', 'zone', name='uq_deck_card_link'),
        Index('idx_deck_card_deck', 'deck_id'),
        Index('idx_deck_card_card', 'card_id'),
    )

    # Relationships
    deck = relationship("DecklistFile", back_populates="card_links")
    card = relationship("MtgCardMirror", back_populates="deck_links")

    def __repr__(self) -> str:
        return (
            f"<DeckCardLink deck={self.deck_id} card={self.card_id} "
            f"qty={self.quantity} zone={self.zone}>"
        )
