from __future__ import annotations

import uuid
from datetime import datetime
from typing import Any

from sqlalchemy import DateTime, ForeignKey, Index, String, Text, UniqueConstraint, func
from sqlalchemy.orm import Mapped, mapped_column
from sqlalchemy.types import JSON

from app.db.base_class import Base


class FewShotSample(Base):
    """已确认的风险观测样本，供 few-shot 检索注入使用。

    数据来源是 ``RiskObservation`` 上人工确认为 confirmed / false_positive 的观测，
    入库后同时写一份向量到 Qdrant 的 ``few_shot_samples`` collection。
    """

    __tablename__ = "few_shot_samples"
    __table_args__ = (
        UniqueConstraint(
            "tenant_id",
            "sample_key",
            name="uq_few_shot_samples_tenant_key",
        ),
        Index(
            "ix_few_shot_samples_tenant_rule_lookup",
            "tenant_id",
            "scene",
            "policy_ref",
            "rule_version",
            "status",
        ),
        Index("ix_few_shot_samples_scene_label", "scene", "label"),
        Index("ix_few_shot_samples_domain_risk_type", "domain", "risk_type"),
    )

    id: Mapped[str] = mapped_column(String(36), primary_key=True, default=lambda: str(uuid.uuid4()))
    tenant_id: Mapped[str] = mapped_column(String(64), default="default", index=True)
    sample_key: Mapped[str] = mapped_column(String(160), index=True)
    source_observation_id: Mapped[str | None] = mapped_column(
        ForeignKey("risk_observations.id"),
        nullable=True,
        index=True,
    )

    scene: Mapped[str] = mapped_column(String(50), default="risk_rule_generation", index=True)
    policy_ref: Mapped[str] = mapped_column(String(160), default="", index=True)
    rule_version: Mapped[str] = mapped_column(String(80), default="", index=True)
    domain: Mapped[str] = mapped_column(String(50), default="", index=True)
    risk_type: Mapped[str] = mapped_column(String(80), default="", index=True)
    risk_level: Mapped[str] = mapped_column(String(20), default="")

    label: Mapped[str] = mapped_column(String(30), default="confirmed", index=True)
    case_text: Mapped[str] = mapped_column(Text(), default="")
    conclusion_text: Mapped[str] = mapped_column(Text(), default="")
    payload_json: Mapped[dict[str, Any]] = mapped_column(JSON, default=dict)

    vector_id: Mapped[str | None] = mapped_column(String(100), nullable=True)
    status: Mapped[str] = mapped_column(String(20), default="active", index=True)

    created_at: Mapped[datetime] = mapped_column(
        DateTime, default=func.now(), server_default=func.now()
    )
    updated_at: Mapped[datetime] = mapped_column(
        DateTime,
        default=func.now(),
        onupdate=func.now(),
        server_default=func.now(),
    )
