from __future__ import annotations

from datetime import datetime
from typing import Literal, Optional

from sqlalchemy import (
    JSON,
    Boolean,
    DateTime,
    Enum,
    ForeignKey,
    Index,
    Numeric,
    func,
)
from sqlalchemy.orm import Mapped, mapped_column

from app.db.base import Base

ContentStage = Literal["general", "expecting", "parenting", "unknown"]


class ContentProfile(Base):
    """
    内容画像表（Content Profile / Cᵢ）。

    字段语义必须严格对齐：
    - `设计说明文档/句子文案打分規則.md`
    """

    __tablename__ = "content_profiles"

    __table_args__ = (
        Index("idx_profiles_stage", "stage"),
        Index("idx_profiles_personalization_power", "personalization_power"),
        Index("idx_profiles_is_safe_pool", "is_safe_pool"),
    )

    content_id: Mapped[int] = mapped_column(
        ForeignKey("contents.content_id", ondelete="CASCADE"),
        primary_key=True,
        comment="FK -> contents.content_id",
    )

    stage: Mapped[ContentStage] = mapped_column(
        Enum("general", "expecting", "parenting", "unknown", name="content_stage"),
        nullable=False,
        server_default="general",
        comment="母职阶段定位（general/expecting/parenting/unknown）",
    )

    emotion_score: Mapped[Optional[float]] = mapped_column(
        Numeric(3, 2),
        nullable=True,
        comment="情绪调性 0~1；NULL 表示 general",
    )

    context_suitability_json: Mapped[dict] = mapped_column(
        JSON,
        nullable=False,
        comment="各 context 的适配度（JSON：0/0.5/1；必须包含 5 个 key）",
    )
    need_suitability_json: Mapped[dict] = mapped_column(
        JSON,
        nullable=False,
        comment="各 need 的适配度（JSON：0/0.5/1；必须包含 5 个 key）",
    )

    personalization_power: Mapped[int] = mapped_column(
        nullable=False,
        server_default="0",
        comment="个性化力度（约定只允许 0/5/10，分别映射 0/0.5/1）",
    )

    review_confidence: Mapped[Optional[float]] = mapped_column(
        Numeric(3, 2),
        nullable=True,
        comment="标注置信度 0~1；NULL 表示由推荐侧按 0.7 兜底",
    )

    is_safe_pool: Mapped[bool] = mapped_column(
        Boolean,
        nullable=False,
        server_default="0",
        comment="是否属于通用安全池（L3 兜底）",
    )

    updated_at: Mapped[datetime] = mapped_column(
        DateTime,
        nullable=False,
        server_default=func.now(),
        server_onupdate=func.now(),
        comment="画像更新时间",
    )

