"""analyze_events 테이블 ORM — POST /documents/{id}/analyze 호출 관측 (Phase E.2)

목적: 분석 failure mode 분류 (timeout / parse / llm / missing_summary) +
      source 별 사용 패턴 (document_server / synology_chat / ui_search / ui_detail / eval).
      단계 3 snapshot DB 설계 입력이 됨.
"""

from datetime import datetime
from typing import Any

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

from core.database import Base


class AnalyzeEvent(Base):
    __tablename__ = "analyze_events"

    id: Mapped[int] = mapped_column(BigInteger, primary_key=True)
    doc_id: Mapped[int] = mapped_column(
        BigInteger, ForeignKey("documents.id", ondelete="CASCADE"), nullable=False
    )
    user_id: Mapped[int | None] = mapped_column(
        BigInteger, ForeignKey("users.id", ondelete="SET NULL")
    )
    mode: Mapped[str] = mapped_column(Text, default="quick", nullable=False)  # quick / full / summary_triage / summary_deep / retrieval_select / synthesis
    text_limit: Mapped[int | None] = mapped_column(Integer)
    truncated: Mapped[bool] = mapped_column(Boolean, default=False)
    layers_returned: Mapped[list[Any] | None] = mapped_column(JSONB, default=list)
    cached: Mapped[bool] = mapped_column(Boolean, default=False)
    latency_ms: Mapped[int | None] = mapped_column(Integer)
    model_name: Mapped[str | None] = mapped_column(Text)
    prompt_version: Mapped[str | None] = mapped_column(Text)
    # None (success) | "timeout" | "llm" | "parse" | "missing_summary" | "no_text"
    error_code: Mapped[str | None] = mapped_column(Text)
    # document_server / synology_chat / ui_search / ui_detail / eval / unknown
    source: Mapped[str] = mapped_column(Text, default="document_server", nullable=False)
    created_at: Mapped[datetime] = mapped_column(
        DateTime(timezone=True), default=datetime.now, nullable=False
    )

    # PR-A (migration 153) — routing shadow observability
    subject_domain: Mapped[str | None] = mapped_column(Text)
    risk_flags: Mapped[list[str] | None] = mapped_column(ARRAY(Text))
    high_impact_task: Mapped[bool | None] = mapped_column(Boolean)
    escalated_to_26b: Mapped[bool | None] = mapped_column(Boolean)
    escalation_reasons: Mapped[list[str] | None] = mapped_column(ARRAY(Text))
    confidence: Mapped[float | None] = mapped_column(Float)
    policy_violation: Mapped[bool | None] = mapped_column(Boolean)
    policy_violation_ids: Mapped[list[str] | None] = mapped_column(ARRAY(Text))
    shadow_would_route_to: Mapped[str | None] = mapped_column(Text)
    policy_version: Mapped[str | None] = mapped_column(Text)

    # PR-B (migration 159) — 실제 호출 tier 와 R2 backlog guard 이벤트
    tier: Mapped[str | None] = mapped_column(Text)                  # 'triage' | 'primary' | 'fallback'
    suppressed_reason: Mapped[str | None] = mapped_column(Text)     # 'backlog_guard(ratio=0.42,pending=7)'

    # PR-B B-2 (migration 161) — /ask 3-state answerability 독립 컬럼
    answerability: Mapped[str | None] = mapped_column(Text)         # 'direct' | 'partial' | 'insufficient'
    partial_basis: Mapped[bool | None] = mapped_column(Boolean)     # partial 답변이 실제 생성됐는지
    suggested_query_count: Mapped[int | None] = mapped_column(Integer)
