"""study_topics / study_topic_documents 테이블 ORM — 학습 워크스페이스 1차 컨테이너

목적: 필기 세션(StudySession) 과 자료(documents) 를 한 학습 주제(예: 가스기사)
      아래로 묶는 컨테이너. 향후 단어장/오디오/문제세트 같은 학습 자산이 같은
      컨테이너 아래로 들어올 수 있도록 설계.

설계 원칙:
  - documents.category(자료실 UI 축) 와 직교한 별도 분류 축. 자료실 facet/카테고리 미터치.
  - StudySession.certification/subject/topic 컬럼은 보존, 본 컨테이너 와 직교 세부 메타.
  - study_type 은 느슨한 분류. DB/Pydantic 강한 enum 미사용. 권장값: certification /
    language / school / work / general (UI 드롭다운에서만 안내).
  - soft delete (deleted_at). 동일 user_id+name 의 active 행만 partial unique index 로
    중복 방지 — 삭제된 주제명 재생성 가능.
  - 자산 다대다 매핑: 본 PR 은 documents 만 (study_topic_documents). 향후 자산 타입별
    조인 테이블 추가 (study_topic_audio_assets 등). polymorphic 단일 테이블 금지.
"""

from datetime import datetime

from sqlalchemy import BigInteger, DateTime, ForeignKey, Integer, String, Text
from sqlalchemy.dialects.postgresql import JSONB
from sqlalchemy.orm import Mapped, mapped_column, relationship

from core.database import Base


class StudyTopic(Base):
    __tablename__ = "study_topics"

    id: Mapped[int] = mapped_column(BigInteger, primary_key=True)
    user_id: Mapped[int] = mapped_column(
        BigInteger, ForeignKey("users.id", ondelete="CASCADE"), nullable=False
    )

    name: Mapped[str] = mapped_column(String(120), nullable=False)
    description: Mapped[str | None] = mapped_column(Text)
    color: Mapped[str | None] = mapped_column(String(20))

    # 느슨한 분류 (certification/language/school/work/general 권장)
    study_type: Mapped[str | None] = mapped_column(String(40))

    sort_order: Mapped[int] = mapped_column(Integer, default=0, nullable=False)

    # PR-6: 시험 메타 (회차당 문항 수 + 과목 리스트)
    exam_round_size: Mapped[int | None] = mapped_column(Integer)
    exam_subjects: Mapped[list] = mapped_column(JSONB, nullable=False, default=list)

    # 공부 암기노트 Phase 1: 공부중 태그 (DDL=migration 295).
    # focused_at IS NOT NULL = 포커스 중 (reminder/세션-prep 대상).
    focused_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True))

    created_at: Mapped[datetime] = mapped_column(
        DateTime(timezone=True), default=datetime.now, nullable=False
    )
    updated_at: Mapped[datetime] = mapped_column(
        DateTime(timezone=True), default=datetime.now, onupdate=datetime.now, nullable=False
    )
    deleted_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True))

    # 연관 — 세션 (1:N), 자료 매핑 (N:M), 문제 (1:N PR-2)
    sessions: Mapped[list["StudySession"]] = relationship(  # type: ignore[name-defined]  # noqa: F821
        "StudySession", back_populates="study_topic", lazy="noload"
    )
    document_links: Mapped[list["StudyTopicDocument"]] = relationship(
        back_populates="topic",
        cascade="all, delete-orphan",
        order_by="StudyTopicDocument.sort_order",
        lazy="noload",
    )
    questions: Mapped[list["StudyQuestion"]] = relationship(  # type: ignore[name-defined]  # noqa: F821
        "StudyQuestion", back_populates="topic", lazy="noload"
    )


class StudyTopicDocument(Base):
    __tablename__ = "study_topic_documents"

    study_topic_id: Mapped[int] = mapped_column(
        BigInteger, ForeignKey("study_topics.id", ondelete="CASCADE"), primary_key=True
    )
    document_id: Mapped[int] = mapped_column(
        BigInteger, ForeignKey("documents.id", ondelete="CASCADE"), primary_key=True
    )
    user_id: Mapped[int] = mapped_column(
        BigInteger, ForeignKey("users.id", ondelete="CASCADE"), nullable=False
    )
    sort_order: Mapped[int] = mapped_column(Integer, default=0, nullable=False)
    created_at: Mapped[datetime] = mapped_column(
        DateTime(timezone=True), default=datetime.now, nullable=False
    )

    topic: Mapped["StudyTopic"] = relationship(back_populates="document_links")
