"""
SQLAlchemy ORM models for the MTG Online database.

Mirrors the original MySQL schema with modern PostgreSQL features.
"""
from sqlalchemy import Column, Integer, String, BigInteger, Boolean, DateTime, Text, ForeignKey, Index
from sqlalchemy.orm import relationship
from sqlalchemy.sql import func
from app.core.database import Base


class User(Base):
    """User account model."""
    __tablename__ = "mtgonline_users"
    
    id = Column(Integer, primary_key=True, index=True)
    username = Column(String(64), unique=True, nullable=False, index=True)
    password_hash = Column(String(128), nullable=False)  # bcrypt hash
    salt = Column(String(128), nullable=False)  # password salt
    email = Column(String(255), nullable=True, index=True)
    country = Column(String(2), nullable=True)
    real_name = Column(String(128), nullable=True)
    avatar_bmp = Column(Text, nullable=True)  # Base64 encoded avatar
    privlevel = Column(String(50), nullable=True, default="User")
    
    # Account status
    is_active = Column(Boolean, default=True)
    is_banned = Column(Boolean, default=False)
    ban_reason = Column(Text, nullable=True)
    ban_ends = Column(DateTime, nullable=True)
    
    # VIP/Donator status
    vip_status = Column(Integer, default=0)  # 0=normal, 1=vip, 2=donator
    vip_expiry = Column(DateTime, nullable=True)
    
    # Timestamps
    creation_date = Column(DateTime, server_default=func.now())
    last_login = Column(DateTime, nullable=True)
    
    # Relationships
    decklist_files = relationship("DecklistFile", back_populates="owner", cascade="all, delete-orphan")
    decklist_folders = relationship("DecklistFolder", back_populates="owner", cascade="all, delete-orphan")
    
    def __repr__(self) -> str:
        return f"<User {self.username} (ID: {self.id})>"


class MtgonlineCard(Base):
    """
    Local card data mirror for the mtgonline database.
    
    Mirrors data from mtg_cards (mtgdata database) to avoid cross-database
    joins during deckbuilding. Maintains source_id to reference the canonical
    mtg_cards.id for sync tracking.
    """
    __tablename__ = "mtgonline_cards"
    
    id = Column(Integer, primary_key=True, index=True)
    source_id = Column(Integer, nullable=True, index=True)  # References mtg_cards.id in mtgdata
    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
    images = Column(Text, nullable=True)  # JSON string
    image = Column(Text, nullable=True)  # Card image URL
    set_code = Column(String(10), nullable=True, index=True)
    set_name = Column(String(255), nullable=True)
    card_parts = Column(Text, nullable=True)  # Comma-separated face names
    keywords = Column(Text, nullable=True)  # Comma-separated keywords
    legalities = Column(Text, nullable=True)  # JSON of format legality
    # Sync tracking
    synced_at = Column(DateTime, server_default=func.now(), onupdate=func.now())
    created_at = Column(DateTime, server_default=func.now())
    
    # Relationships
    deck_cards = relationship(
        "UserDeckCard",
        back_populates="card",
        cascade="all, delete-orphan"
    )
    
    # Indexes
    __table_args__ = (
        Index('idx_mtgonline_cards_name', 'name'),
        Index('idx_mtgonline_cards_set', 'set_code'),
    )
    
    def __repr__(self) -> str:
        return f"<MtgonlineCard {self.name} (ID: {self.id}, source: {self.source_id})>"


class DecklistFolder(Base):
    """User deck folder."""
    __tablename__ = "mtgonline_decklist_folders"
    
    id = Column(Integer, primary_key=True, index=True)
    owner_id = Column(Integer, ForeignKey("mtgonline_users.id"), nullable=False)
    name = Column(String(255), nullable=False)
    parent_id = Column(Integer, ForeignKey("mtgonline_decklist_folders.id"), nullable=True)
    creation_date = Column(DateTime, server_default=func.now())
    
    # Relationships
    owner = relationship("User", back_populates="decklist_folders")
    children = relationship("DecklistFolder", back_populates="parent", cascade="all, delete-orphan")
    parent = relationship("DecklistFolder", back_populates="children", remote_side=[id])
    files = relationship("DecklistFile", back_populates="folder", cascade="all, delete-orphan")
    user_decks = relationship(
        "UserDeck",
        back_populates="folder",
        lazy="select"
    )


class DecklistFile(Base):
    """Deck file stored in a folder."""
    __tablename__ = "mtgonline_decklist_files"
    
    id = Column(Integer, primary_key=True, index=True)
    folder_id = Column(Integer, ForeignKey("mtgonline_decklist_folders.id"), nullable=True)
    owner_id = Column(Integer, ForeignKey("mtgonline_users.id"), nullable=False)
    name = Column(String(255), nullable=False)
    content = Column(Text, nullable=False)  # Native XML or plain text deck format
    format = Column(String(50), default="native")  # 'native' or 'plain'
    status = Column(String(20), default="DRAUGHT")  # 'DRAUGHT' or 'FINAL'
    creation_date = Column(DateTime, server_default=func.now())
    
    # Relationships
    folder = relationship("DecklistFolder", back_populates="files")
    owner = relationship("User", back_populates="decklist_files")
    
    def __repr__(self) -> str:
        return f"<DecklistFile {self.name} (ID: {self.id})>"


class Room(Base):
    """Chat room."""
    __tablename__ = "mtgonline_rooms"
    
    id = Column(Integer, primary_key=True, index=True)
    name = Column(String(100), unique=True, nullable=False)
    description = Column(Text, nullable=True)
    is_password_protected = Column(Boolean, default=False)
    password_hash = Column(String(128), nullable=True)
    creation_date = Column(DateTime, server_default=func.now())
    
    # Game types available in this room
    game_types = relationship("RoomGameType", back_populates="room", cascade="all, delete-orphan")


class RoomGameType(Base):
    """Game type definition for a room."""
    __tablename__ = "mtgonline_rooms_gametypes"
    
    id = Column(Integer, primary_key=True, index=True)
    room_id = Column(Integer, ForeignKey("mtgonline_rooms.id"), nullable=False)
    name = Column(String(100), nullable=False)
    description = Column(Text, nullable=True)
    
    # Relationships
    room = relationship("Room", back_populates="game_types")


class Ban(Base):
    """User ban record."""
    __tablename__ = "mtgonline_bans"
    
    id = Column(Integer, primary_key=True, index=True)
    user_id = Column(Integer, ForeignKey("mtgonline_users.id"), nullable=False)
    server_id = Column(Integer, nullable=True)
    reason = Column(Text, nullable=False)
    moderators = Column(String(255), nullable=True)  # Admin usernames
    ip_address = Column(String(45), nullable=True)  # IPv4 or IPv6
    expiration_time = Column(DateTime, nullable=True)
    active = Column(Boolean, default=True)
    creation_date = Column(DateTime, server_default=func.now())
    
    # Relationships
    user = relationship("User")
    
    def __repr__(self) -> str:
        return f"<Ban for User {self.user_id} (ID: {self.id})>"


class GameLog(Base):
    """Game log entry."""
    __tablename__ = "mtgonline_log"
    
    id = Column(Integer, primary_key=True, index=True)
    room_id = Column(Integer, ForeignKey("mtgonline_rooms.id"), nullable=True)
    player_id = Column(Integer, ForeignKey("mtgonline_users.id"), nullable=True)
    message = Column(Text, nullable=False)
    timestamp = Column(DateTime, server_default=func.now())
    
    # Relationships
    room = relationship("Room")
    player = relationship("User")


class AuditLog(Base):
    """Audit trail for administrative actions."""
    __tablename__ = "mtgonline_audit"
    
    id = Column(Integer, primary_key=True, index=True)
    admin_id = Column(Integer, ForeignKey("mtgonline_users.id"), nullable=False)
    action_type = Column(String(50), nullable=False)  # 'ban', 'unban', 'warn', etc.
    target_user_id = Column(Integer, ForeignKey("mtgonline_users.id"), nullable=True)
    details = Column(Text, nullable=True)
    ip_address = Column(String(45), nullable=True)
    timestamp = Column(DateTime, server_default=func.now())
    
    # Relationships
    admin = relationship("User", foreign_keys=[admin_id])
    target_user = relationship("User", foreign_keys=[target_user_id])


# Indexes for performance
Index("idx_decks_owner", DecklistFile.owner_id)
Index("idx_decks_folder", DecklistFile.folder_id)
Index("idx_bans_active", Ban.active)
Index("idx_log_timestamp", GameLog.timestamp)
