"""穿山甲 GroMore 天级收益报表(后台结算口径,定时拉取入库)。

每行 = GroMore 数据 API 返回的一条「日期 × 应用 × 代码位」聚合收益(`integrations/pangle_report`
+ `scripts/sync_pangle_revenue` 落库)。**权威/预估收益的来源**,与 `ad_ecpm_record`(客户端自报
eCPM 折算的预估)互为对照:

- `revenue_yuan` ← 接口 `revenue`(预估收益,元;排序价×展示/1000,所有 ADN 都有);
- `api_revenue_yuan` ← 接口 `api_revenue`(收益Api,元;各 ADN 经 Reporting 回传、更接近结算;
  未配置该 ADN 的 Reporting 或查当天时为空)。

⚠️ 穿山甲不提供分用户/设备维度,故本表最细只到 日期×应用×代码位,**无法挂到逐条广告事件**;
广告收益报表里只用于汇总/趋势级的「穿山甲后台收益」,不改逐条行的客户端预估。
"""
from __future__ import annotations

from datetime import datetime

from sqlalchemy import (
    DateTime,
    Float,
    Integer,
    String,
    UniqueConstraint,
    func,
)
from sqlalchemy.orm import Mapped, mapped_column

from app.db.base import Base


class AdPangleDailyRevenue(Base):
    __tablename__ = "ad_pangle_daily_revenue"
    __table_args__ = (
        # 一行 = (日期, 应用, 代码位, 广告源);adn 用 "" 表示「未分广告源、该代码位汇总」,
        # 避免 NULL 在唯一约束里被视为各不相同导致 upsert 重复(SQLite/PG 行为一致)。
        UniqueConstraint(
            "report_date", "app_env", "our_code_id", "adn",
            name="uq_ad_pangle_daily",
        ),
    )

    id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
    # 北京时间日期串 'YYYY-MM-DD'(拉取时 time_zone=8),与 ad_ecpm_record.report_date 同口径,可直接 join。
    report_date: Mapped[str] = mapped_column(String(10), index=True, nullable=False)
    # 我们的应用环境:prod(傻瓜比价正式)/ test(测试);由 site_id 经 settings 映射而来。
    app_env: Mapped[str] = mapped_column(String(16), nullable=False)
    # 原始 GroMore AppId(site_id),留痕便于排查映射。
    site_id: Mapped[str | None] = mapped_column(String(32), nullable=True)
    # 广告位 ID(= 接口 ad_unit_id = 我们客户端配的 104xxx = ad_ecpm_record.our_code_id),join key。
    # ⚠️ 不是接口的 code_id —— 那是底层各 ADN 的代码位(如 983674557),对不上我们的口径。
    our_code_id: Mapped[str] = mapped_column(String(64), index=True, nullable=False)
    # 广告源(接口 network 数字→名,如 pangle/gdt);"" = 未分广告源的代码位汇总行(当前默认口径)。
    adn: Mapped[str] = mapped_column(String(16), nullable=False, default="")
    # 预估收益(元)← 接口 revenue。
    revenue_yuan: Mapped[float] = mapped_column(Float, nullable=False, default=0.0)
    # 收益Api(元)← 接口 api_revenue;未配 Reporting / 当天 等情况接口不返回 → NULL。
    api_revenue_yuan: Mapped[float | None] = mapped_column(Float, nullable=True)
    # 预估 eCPM 原值(接口 ecpm,单位元/千次,**与客户端 getEcpm 的「分」不同**),参考用原样存。
    ecpm: Mapped[str | None] = mapped_column(String(32), nullable=True)
    # 展示次数 ← 接口 imp_cnt。
    impressions: Mapped[int] = mapped_column(Integer, nullable=False, default=0)
    # 货币类型(接口 currency,正常为 cny)。
    currency: Mapped[str] = mapped_column(String(8), nullable=False, default="cny")
    # 最近一次同步写入时间(同一行可被多次回补覆盖;T+1 数据穿山甲会订正)。
    synced_at: Mapped[datetime] = mapped_column(
        DateTime(timezone=True), server_default=func.now(), onupdate=func.now(), nullable=False
    )

    def __repr__(self) -> str:  # pragma: no cover
        return (
            f"<AdPangleDailyRevenue {self.report_date} {self.app_env} "
            f"code={self.our_code_id} revenue={self.revenue_yuan}>"
        )
