"""
Home 모듈 SQLAlchemy 모델 정의

이 모듈은 영상 제작 파이프라인의 핵심 데이터 모델을 정의합니다.
- Project: 프로젝트(사용자 입력 이력) 관리
- Image: 업로드된 이미지 URL 관리
"""

from datetime import datetime
from typing import TYPE_CHECKING, List, Optional

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

from app.database.session import Base

if TYPE_CHECKING:
    from app.lyric.models import Lyric
    from app.song.models import Song
    from app.video.models import Video


class Project(Base):
    """
    프로젝트 테이블 (사용자 입력 이력)

    영상 제작 요청의 시작점으로, 고객 정보와 지역 정보를 저장합니다.
    하위 테이블(Lyric, Song, Video)의 부모 테이블 역할을 합니다.

    Attributes:
        id: 고유 식별자 (자동 증가)
        store_name: 고객명 (필수)
        region: 지역명 (필수, 예: 서울, 부산, 대구 등)
        task_id: 작업 고유 식별자 (UUID 형식, 36자)
        detail_region_info: 상세 지역 정보 (선택, JSON 또는 텍스트 형식)
        created_at: 생성 일시 (자동 설정)

    Relationships:
        lyrics: 생성된 가사 목록
        songs: 생성된 노래 목록
        videos: 최종 영상 결과 목록
    """

    __tablename__ = "project"
    __table_args__ = (
        Index("idx_project_task_id", "task_id"),
        Index("idx_project_store_name", "store_name"),
        Index("idx_project_region", "region"),
        {
            "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="고유 식별자",
    )

    store_name: Mapped[str] = mapped_column(
        String(255),
        nullable=False,
        index=True,
        comment="가게명",
    )

    region: Mapped[str] = mapped_column(
        String(100),
        nullable=False,
        index=True,
        comment="지역명 (예: 군산)",
    )

    task_id: Mapped[str] = mapped_column(
        String(36),
        nullable=False,
        comment="프로젝트 작업 고유 식별자 (UUID)",
    )

    detail_region_info: Mapped[Optional[str]] = mapped_column(
        Text,
        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=False,
        server_default=func.now(),
        comment="생성 일시",
    )

    # Relationships
    lyrics: Mapped[List["Lyric"]] = relationship(
        "Lyric",
        back_populates="project",
        cascade="all, delete-orphan",
        lazy="selectin",
    )

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

    videos: Mapped[List["Video"]] = relationship(
        "Video",
        back_populates="project",
        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"<Project("
            f"id={self.id}, "
            f"store_name='{self.store_name}', "
            f"task_id='{truncate(self.task_id)}'"
            f")>"
        )


class Image(Base):
    """
    업로드 이미지 테이블

    사용자가 업로드한 이미지의 URL을 저장합니다.
    독립적으로 관리되며 Project와 직접적인 관계가 없습니다.

    Attributes:
        id: 고유 식별자 (자동 증가)
        task_id: 이미지 업로드 작업 고유 식별자 (UUID)
        img_name: 이미지명
        img_url: 이미지 URL (S3, CDN 등의 경로)
        created_at: 생성 일시 (자동 설정)
    """

    __tablename__ = "image"
    __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="고유 식별자",
    )

    task_id: Mapped[str] = mapped_column(
        String(36),
        nullable=False,
        comment="이미지 업로드 작업 고유 식별자 (UUID)",
    )

    img_name: Mapped[str] = mapped_column(
        String(255),
        nullable=False,
        comment="이미지명",
    )

    img_url: Mapped[str] = mapped_column(
        String(2048),
        nullable=False,
        comment="이미지 URL (blob, CDN 경로)",
    )

    img_order: Mapped[int] = mapped_column(
        Integer,
        nullable=False,
        default=0,
        comment="이미지 순서",
    )

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

    def __repr__(self) -> str:
        task_id_str = (
            (self.task_id[:10] + "...") if len(self.task_id) > 10 else self.task_id
        )
        img_name_str = (
            (self.img_name[:10] + "...") if len(self.img_name) > 10 else self.img_name
        )

        return (
            f"<Image(id={self.id}, task_id='{task_id_str}', img_name='{img_name_str}')>"
        )
