"""SQLAlchemy models for the media service."""

import uuid
from datetime import datetime

from sqlalchemy import (
    Column, String, Text, Integer, BigInteger, Boolean, Float,
    DateTime, ForeignKey, Index, UniqueConstraint,
)
from sqlalchemy.dialects.postgresql import UUID
from sqlalchemy.orm import relationship

from app.database import Base


class Show(Base):
    __tablename__ = "media_shows"

    id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
    user_id = Column(String(64), nullable=False, index=True)
    title = Column(String(500), nullable=False)
    author = Column(String(500))
    description = Column(Text)
    artwork_url = Column(Text)
    feed_url = Column(Text)
    local_path = Column(Text)
    show_type = Column(String(20), nullable=False, default="podcast")
    etag = Column(String(255))
    last_modified = Column(String(255))
    last_fetched_at = Column(DateTime)
    created_at = Column(DateTime, default=datetime.utcnow)
    updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)

    episodes = relationship("Episode", back_populates="show", cascade="all, delete-orphan")


class Episode(Base):
    __tablename__ = "media_episodes"
    __table_args__ = (
        UniqueConstraint("show_id", "guid", name="uq_media_episodes_show_guid"),
        Index("idx_media_episodes_show", "show_id"),
        Index("idx_media_episodes_published", "published_at"),
    )

    id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
    show_id = Column(UUID(as_uuid=True), ForeignKey("media_shows.id", ondelete="CASCADE"))
    user_id = Column(String(64), nullable=False)
    title = Column(String(1000))
    description = Column(Text)
    audio_url = Column(Text)
    duration_seconds = Column(Integer)
    file_size_bytes = Column(BigInteger)
    published_at = Column(DateTime)
    guid = Column(String(500))
    artwork_url = Column(Text)
    is_downloaded = Column(Boolean, default=False)
    created_at = Column(DateTime, default=datetime.utcnow)

    show = relationship("Show", back_populates="episodes")
    progress = relationship("Progress", back_populates="episode", uselist=False, cascade="all, delete-orphan")


class Progress(Base):
    __tablename__ = "media_progress"
    __table_args__ = (
        UniqueConstraint("user_id", "episode_id", name="uq_media_progress_user_episode"),
        Index("idx_media_progress_user", "user_id"),
    )

    id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
    user_id = Column(String(64), nullable=False)
    episode_id = Column(UUID(as_uuid=True), ForeignKey("media_episodes.id", ondelete="CASCADE"))
    position_seconds = Column(Float, default=0)
    duration_seconds = Column(Integer)
    is_completed = Column(Boolean, default=False)
    playback_speed = Column(Float, default=1.0)
    last_played_at = Column(DateTime, default=datetime.utcnow)

    episode = relationship("Episode", back_populates="progress")


class QueueItem(Base):
    __tablename__ = "media_queue"
    __table_args__ = (
        UniqueConstraint("user_id", "episode_id", name="uq_media_queue_user_episode"),
        Index("idx_media_queue_user_order", "user_id", "sort_order"),
    )

    id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
    user_id = Column(String(64), nullable=False)
    episode_id = Column(UUID(as_uuid=True), ForeignKey("media_episodes.id", ondelete="CASCADE"))
    sort_order = Column(Integer, nullable=False, default=0)
    added_at = Column(DateTime, default=datetime.utcnow)

    episode = relationship("Episode")


class PlaybackEvent(Base):
    __tablename__ = "media_playback_events"

    id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
    user_id = Column(String(64), nullable=False)
    episode_id = Column(UUID(as_uuid=True), ForeignKey("media_episodes.id", ondelete="CASCADE"))
    event_type = Column(String(20), nullable=False)
    position_seconds = Column(Float)
    playback_speed = Column(Float, default=1.0)
    created_at = Column(DateTime, default=datetime.utcnow)

    episode = relationship("Episode")
