from datetime import datetime
from typing import TYPE_CHECKING, Optional

from sqlalchemy import DateTime, ForeignKey, Integer, String, func
from sqlalchemy.orm import Mapped, mapped_column, relationship

from app.database.session import Base

if TYPE_CHECKING:
    from app.home.models import Project
    from app.lyric.models import Lyric
    from app.song.models import Song


class Video(Base):
    """
    영상 결과 테이블

    최종 생성된 영상의 결과 URL을 저장합니다.
    Creatomate 서비스를 통해 이미지와 노래를 결합한 영상 결과입니다.

    Attributes:
        id: 고유 식별자 (자동 증가)
        project_id: 연결된 Project의 id (외래키)
        lyric_id: 연결된 Lyric의 id (외래키)
        song_id: 연결된 Song의 id (외래키)
        task_id: 영상 생성 작업의 고유 식별자 (UUID 형식)
        status: 처리 상태 (pending, processing, completed, failed 등)
        result_movie_url: 생성된 영상 URL (S3, CDN 경로)
        created_at: 생성 일시 (자동 설정)

    Relationships:
        project: 연결된 Project
        lyric: 연결된 Lyric
        song: 연결된 Song
    """

    __tablename__ = "video"
    __table_args__ = (
        {
            "mysql_engine": "InnoDB",
            "mysql_charset": "utf8mb4",
            "mysql_collate": "utf8mb4_unicode_ci",
        },
    )

    id: Mapped[int] = mapped_column(
        Integer,
        primary_key=True,
        nullable=False,
        autoincrement=True,
        comment="고유 식별자",
    )

    project_id: Mapped[int] = mapped_column(
        Integer,
        ForeignKey("project.id", ondelete="CASCADE"),
        nullable=False,
        index=True,
        comment="연결된 Project의 id",
    )

    lyric_id: Mapped[int] = mapped_column(
        Integer,
        ForeignKey("lyric.id", ondelete="CASCADE"),
        nullable=False,
        index=True,
        comment="연결된 Lyric의 id",
    )

    song_id: Mapped[int] = mapped_column(
        Integer,
        ForeignKey("song.id", ondelete="CASCADE"),
        nullable=False,
        index=True,
        comment="연결된 Song의 id",
    )

    task_id: Mapped[str] = mapped_column(
        String(36),
        nullable=False,
        index=True,
        comment="영상 생성 작업 고유 식별자 (UUID)",
    )

    creatomate_render_id: Mapped[Optional[str]] = mapped_column(
        String(64),
        nullable=True,
        comment="Creatomate API 렌더 ID",
    )

    status: Mapped[str] = mapped_column(
        String(50),
        nullable=False,
        comment="처리 상태 (processing, completed, failed)",
    )

    result_movie_url: Mapped[Optional[str]] = mapped_column(
        String(2048),
        nullable=True,
        comment="생성된 영상 URL",
    )

    created_at: Mapped[datetime] = mapped_column(
        DateTime,
        nullable=False,
        server_default=func.now(),
        comment="생성 일시",
    )

    # Relationships
    project: Mapped["Project"] = relationship(
        "Project",
        back_populates="videos",
    )

    lyric: Mapped["Lyric"] = relationship(
        "Lyric",
        back_populates="videos",
    )

    song: Mapped["Song"] = relationship(
        "Song",
        back_populates="videos",
    )

    def __repr__(self) -> str:
        def truncate(value: str | None, max_len: int = 10) -> str:
            if value is None:
                return "None"
            return (value[:max_len] + "...") if len(value) > max_len else value

        return (
            f"<Video("
            f"id={self.id}, "
            f"task_id='{truncate(self.task_id)}', "
            f"status='{self.status}'"
            f")>"
        )
