from datetime import datetime
from typing import TYPE_CHECKING, List

from sqlalchemy import DateTime, ForeignKey, Integer, String, Text, func
from sqlalchemy.dialects.mysql import LONGTEXT
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.song.models import Song
    from app.video.models import Video


class Lyric(Base):
    """
    가사 테이블

    AI를 통해 생성된 가사 정보를 저장합니다.
    프롬프트와 생성 결과, 처리 상태를 관리합니다.

    Attributes:
        id: 고유 식별자 (자동 증가)
        project_id: 연결된 Project의 id (외래키)
        task_id: 가사 생성 작업의 고유 식별자 (UUID 형식)
        status: 처리 상태 (pending, processing, completed, failed 등)
        lyric_prompt: 가사 생성에 사용된 프롬프트
        lyric_result: 생성된 가사 결과 (LONGTEXT로 긴 가사 지원)
        created_at: 생성 일시 (자동 설정)

    Relationships:
        project: 연결된 Project
        songs: 이 가사를 사용한 노래 목록
        videos: 이 가사를 사용한 영상 목록
    """

    __tablename__ = "lyric"
    __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",
    )

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

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

    lyric_prompt: Mapped[str] = mapped_column(
        Text,
        nullable=False,
        comment="가사 생성에 사용된 프롬프트",
    )

    lyric_result: Mapped[str] = mapped_column(
        LONGTEXT,
        nullable=True,
        comment="생성된 가사 결과",
    )

    language: Mapped[str] = mapped_column(
        String(50),
        nullable=False,
        default="Korean",
        comment="가사 출력 언어 (Korean, English, Chinese, Japanese, Thai, Vietnamese)",
    )

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

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

    songs: Mapped[List["Song"]] = relationship(
        "Song",
        back_populates="lyric",
        cascade="all, delete-orphan",
        lazy="selectin",
    )

    videos: Mapped[List["Video"]] = relationship(
        "Video",
        back_populates="lyric",
        cascade="all, delete-orphan",
        lazy="selectin",
    )

    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"<Lyric("
            f"id={self.id}, "
            f"task_id='{truncate(self.task_id)}', "
            f"status='{self.status}'"
            f")>"
        )
