"""价格观测内部上报的收发模型。

pricebot 在比价 done 帧 server→server POST 一批观测(一次比价 = 源 + N 目标平台各一条)。
批级字段(门店 / 菜篮 / 地理 / 来源)所有观测共享,放外层;逐平台字段放 observations[]。
"""
from __future__ import annotations

from pydantic import BaseModel, Field


class PriceObservationItem(BaseModel):
    """单个平台的价格观测(一次比价里的一行)。"""

    platform: str
    is_source: bool = False
    scope: str = "order"                          # order / dish
    price_cents: int | None = None                # 到手价(分);None=该平台失败/打烊
    coupon_saved_cents: int | None = None
    coupon_name: str | None = None
    store_closed: str | None = None               # 打烊原因(非空时 price_cents=None)
    rank: int | None = None                        # 全局名次(1=最便宜)
    platform_store_id: str | None = None
    attrs: dict | None = None                      # 该平台的灵活明细兜底


class PriceObservationBatchIn(BaseModel):
    """一次比价的整批价格观测上报体。"""

    trace_id: str
    business_type: str = "food"
    # 门店 / 菜篮 / 地理 —— 一次比价同一份,批级共享
    store_name: str | None = None
    city: str | None = None
    geohash: str | None = None
    lng: float | None = None
    lat: float | None = None
    dishes: list | None = None                     # [{name, qty, subtotal?}]
    # 来源
    source_device_id: str | None = None
    source_user_id: int | None = None
    # 逐平台观测(源 + 各目标)
    observations: list[PriceObservationItem] = Field(default_factory=list)


class PriceObservationBatchOut(BaseModel):
    """上报结果:本批新写入条数 / 因幂等跳过条数。"""

    inserted: int
    skipped: int
