"""study_question_progress — 사용자 × 토픽 × 문제 단위 현재 상태 캐시 (Phase 1).

attempts (append-only 원본 로그) 와 분리. 한 번 박힌 attempts 는 절대 update 안 함.
progress 는 마지막 시도 / 사용자 검토 / 복습 큐 / 패턴 분류 derived 4 차원 메타.

세션 종료 시 finalize 가 다음 갱신:
    - last_outcome / last_attempted_at / last_attempt_id
    - pattern_state / pattern_updated_at / pattern_window_attempts
    - (이미 due_at 박힌 행만) review_stage / due_at  ← 복습 stage 갱신

review-complete 가 다음 갱신:
    - last_reviewed_at
    - (wrong/unsure 인 경우) due_at 최초 부여

study_question_id 는 단일 topic 소속 전제 (현재 가스기사 토픽 4 단일 운영). 향후 question
재사용/N:M 가능성 대비 unique 키는 (user_id, study_topic_id, study_question_id) 3 키.
"""

from __future__ import annotations

from datetime import datetime

from sqlalchemy import BigInteger, DateTime, ForeignKey, Integer, SmallInteger, String, UniqueConstraint
from sqlalchemy.orm import Mapped, mapped_column

from core.database import Base


class StudyQuestionProgress(Base):
    __tablename__ = "study_question_progress"
    __table_args__ = (
        UniqueConstraint(
            "user_id", "study_topic_id", "study_question_id",
            name="uq_progress_user_topic_question",
        ),
    )

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

    # 마지막 시도 요약
    last_outcome: Mapped[str | None] = mapped_column(String(20))
    last_attempted_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True))
    last_attempt_id: Mapped[int | None] = mapped_column(
        BigInteger, ForeignKey("study_question_attempts.id", ondelete="SET NULL")
    )

    # 사용자 검토 상태
    last_reviewed_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True))

    # 복습 큐
    due_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True))
    review_stage: Mapped[int | None] = mapped_column(SmallInteger)

    # 패턴 분류 (derived)
    pattern_state: Mapped[str | None] = mapped_column(String(30))
    pattern_updated_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True))
    pattern_window_attempts: Mapped[int | None] = mapped_column(SmallInteger)

    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
    )
