"""morning_briefings + briefing_topics 테이블 ORM (야간 수집 뉴스 브리핑).

axis 반대: Phase 4 = country×topic / Briefing = topic×country.
country_perspectives JSONB 안에 한 topic 의 여러 국가 관점 array.
"""

from datetime import date, datetime

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

from core.database import Base


class MorningBriefing(Base):
    """하루 단위 브리핑 메타데이터 (KST 자정~05:00 윈도우)"""

    __tablename__ = "morning_briefings"

    id: Mapped[int] = mapped_column(BigInteger, primary_key=True)
    briefing_date: Mapped[date] = mapped_column(Date, nullable=False, unique=True)
    window_start: Mapped[datetime] = mapped_column(DateTime(timezone=True), nullable=False)
    window_end: Mapped[datetime] = mapped_column(DateTime(timezone=True), nullable=False)
    decay_lambda: Mapped[float] = mapped_column(Float, nullable=False)

    total_articles: Mapped[int] = mapped_column(Integer, nullable=False, default=0)
    total_countries: Mapped[int] = mapped_column(Integer, nullable=False, default=0)
    total_topics: Mapped[int] = mapped_column(Integer, nullable=False, default=0)

    generation_ms: Mapped[int | None] = mapped_column(Integer)
    llm_calls: Mapped[int] = mapped_column(Integer, nullable=False, default=0)
    llm_failures: Mapped[int] = mapped_column(Integer, nullable=False, default=0)
    status: Mapped[str] = mapped_column(String(20), nullable=False, default="success")

    headline_oneliner: Mapped[str | None] = mapped_column(Text)

    created_at: Mapped[datetime] = mapped_column(
        DateTime(timezone=True), nullable=False, default=datetime.now
    )

    topics: Mapped[list["BriefingTopic"]] = relationship(
        back_populates="briefing",
        cascade="all, delete-orphan",
        order_by="BriefingTopic.topic_rank",
    )


class BriefingTopic(Base):
    """1 briefing 안 topic_rank 순 cross-country 비교 분석 결과"""

    __tablename__ = "briefing_topics"

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

    topic_rank: Mapped[int] = mapped_column(Integer, nullable=False)
    topic_label: Mapped[str] = mapped_column(String(120), nullable=False)
    headline: Mapped[str] = mapped_column(Text, nullable=False)

    country_perspectives: Mapped[list] = mapped_column(JSONB, nullable=False, default=list)
    divergences: Mapped[list] = mapped_column(JSONB, nullable=False, default=list)
    convergences: Mapped[list] = mapped_column(JSONB, nullable=False, default=list)
    key_quotes: Mapped[list] = mapped_column(JSONB, nullable=False, default=list)

    historical_article_ids: Mapped[list | None] = mapped_column(JSONB)
    historical_context: Mapped[str | None] = mapped_column(Text)
    historical_window_days: Mapped[int | None] = mapped_column(Integer)

    cluster_members: Mapped[list] = mapped_column(JSONB, nullable=False, default=list)
    article_count: Mapped[int] = mapped_column(Integer, nullable=False)
    country_count: Mapped[int] = mapped_column(Integer, nullable=False)
    importance_score: Mapped[float] = mapped_column(Float, nullable=False)
    raw_weight_sum: Mapped[float] = mapped_column(Float, nullable=False)

    llm_model: Mapped[str | None] = mapped_column(String(100))
    llm_fallback_used: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False)

    # 2026-05-13 카드별 사용자 액션 (date picker 와 동반).
    is_read: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False)
    read_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True))
    highlighted: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False)
    highlighted_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True))

    created_at: Mapped[datetime] = mapped_column(
        DateTime(timezone=True), nullable=False, default=datetime.now
    )

    briefing: Mapped["MorningBriefing"] = relationship(back_populates="topics")
