"""ask_events 테이블 ORM — /ask 호출 관측 (Phase 3.5a migration 102, Phase 3.5b 배선)

threshold calibration + verifier FP 분석 + defense layer 디버깅 데이터.
"""

from datetime import datetime
from typing import Any

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

from core.database import Base


class AskEvent(Base):
    __tablename__ = "ask_events"

    id: Mapped[int] = mapped_column(BigInteger, primary_key=True)
    query: Mapped[str] = mapped_column(Text, nullable=False)
    user_id: Mapped[int | None] = mapped_column(
        BigInteger, ForeignKey("users.id", ondelete="SET NULL")
    )
    completeness: Mapped[str | None] = mapped_column(Text)  # full / partial / insufficient
    synthesis_status: Mapped[str | None] = mapped_column(Text)
    confidence: Mapped[str | None] = mapped_column(Text)  # high / medium / low
    refused: Mapped[bool] = mapped_column(Boolean, default=False, nullable=False)
    classifier_verdict: Mapped[str | None] = mapped_column(Text)  # sufficient / insufficient
    max_rerank_score: Mapped[float | None] = mapped_column(Float)
    aggregate_score: Mapped[float | None] = mapped_column(Float)
    hallucination_flags: Mapped[list[Any] | None] = mapped_column(JSONB, default=list)
    evidence_count: Mapped[int | None] = mapped_column(Integer)
    citation_count: Mapped[int | None] = mapped_column(Integer)
    defense_layers: Mapped[dict[str, Any] | None] = mapped_column(JSONB)
    total_ms: Mapped[int | None] = mapped_column(Integer)
    # Phase E.1: 측정 필드 확장 (answer_length가 E.3 400→600자 비교 핵심)
    answer_length: Mapped[int | None] = mapped_column(Integer)
    covered_aspects: Mapped[list[Any] | None] = mapped_column(JSONB)
    missing_aspects: Mapped[list[Any] | None] = mapped_column(JSONB)
    model_name: Mapped[str | None] = mapped_column(Text)
    prompt_version: Mapped[str | None] = mapped_column(Text)
    # Phase 3.5 calibration: eval/production 분리 + golden join 키
    # 138~141 단계: nullable. 142 적용 후 source 는 NOT NULL (DB 강제, 앱은 항상 채움).
    source: Mapped[str | None] = mapped_column(Text)
    eval_case_id: Mapped[str | None] = mapped_column(Text)
    created_at: Mapped[datetime] = mapped_column(
        DateTime(timezone=True), default=datetime.now, nullable=False
    )
