"""启动确认窗 agent 兜底样本表(launch_confirm_sample)。

pricebot 的 launch_confirm_agent 每次"静态 PROFILES 没认出、靠 LLM 兜底放行"一个跨 App
启动确认窗(繁体 / 英文 / 小语种 / ROM 改版)时,把完整样本 server→server 落这里。研发定期
**人工**把 exec_success=true 的样本沉淀进 pricebot 的 launch_confirm.PROFILES(静态快路径),
让以后同款窗不必再调 LLM。

设计:
- 与登录无关、不鉴权(server→server 共享密钥头 X-Internal-Secret)。
- **都上报、不去重**(by design):同一种窗多台机器上报多条,研发按 host_package / locale
  聚合后人工筛。
- 大字段(弹窗树快照 + LLM plan + 设备信息)塞 payload(JSONB)兜底,免得加字段就迁移 schema。
"""
from __future__ import annotations

from datetime import datetime

from sqlalchemy import JSON, Boolean, DateTime, Integer, String, func
from sqlalchemy.dialects.postgresql import JSONB
from sqlalchemy.orm import Mapped, mapped_column

from app.db.base import Base

# PG 上用 JSONB(可建 GIN 索引),SQLite(本地/测试)退化为通用 JSON(同 price_observation)。
_JSON = JSON().with_variant(JSONB(), "postgresql")


class LaunchConfirmSample(Base):
    __tablename__ = "launch_confirm_sample"

    id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
    created_at: Mapped[datetime] = mapped_column(
        DateTime(timezone=True), server_default=func.now(), index=True, nullable=False
    )

    # pricebot 侧 trace_id:回指原始 trace,能去 price.shaguabijia.com 查完整上下文。
    trace_id: Mapped[str | None] = mapped_column(String(64), index=True, nullable=True)
    device_id: Mapped[str | None] = mapped_column(String(64), index=True, nullable=True)

    # 弹窗宿主包(= 触发判据, 也是研发沉淀进 PROFILES.host_packages 的键)。按它聚合人工筛。
    host_package: Mapped[str | None] = mapped_column(String(128), index=True, nullable=True)
    # 被打开的目标 App 包名(标题里"想要打开 X"的 X 是变量, 据此把它从 sign 里挖空)。
    target_app: Mapped[str | None] = mapped_column(String(128), nullable=True)
    # 系统语言地区(zh-TW / en-US…)—— 多语言问题的核心维度。
    # ⚠️ 前端 AgentStepRequest 暂未上报设备信息 → 现恒 None,待前端加 device_info 字段后回填。
    system_locale: Mapped[str | None] = mapped_column(String(32), index=True, nullable=True)

    # 这次兜底是否成功放行(弹窗消失=True;放弃 / LLM 没认出=False)。研发只沉淀 True 的。
    exec_success: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False)
    # 弹窗标题全文(研发据此提 launch_sign),如"「傻瓜比价」想要開啟「京東」"。
    dialog_title: Mapped[str | None] = mapped_column(String(256), nullable=True)

    # 大 JSON:完整样本。{is_launch_confirm, llm_model, llm_reason, plan, dialog_tree,
    #   device_info: {screen, locale, brand, model, android_version, rom_version}}
    payload: Mapped[dict | None] = mapped_column(_JSON, nullable=True)

    def __repr__(self) -> str:  # pragma: no cover
        return (
            f"<LaunchConfirmSample id={self.id} host={self.host_package!r} "
            f"locale={self.system_locale!r} success={self.exec_success}>"
        )
