"""广告展示 eCPM 上报记录(内部收益统计/对账)。

每条 = 客户端一次广告展示(`onAdShow`)后读到的 eCPM 信息。`ad_session_id`
由客户端生成,并通过激励视频 extra 透传给 S2S 回调,用于把"展示 eCPM"与
"奖励完成"绑定。没有 session id 的旧上报仍可作为按天对账补充。

`ecpm_raw` 原样存客户端上报的字符串——单位是穿山甲 getEcpm 官方口径【分/千次展示】
(非元!),对账由 `core/rewards.parse_ecpm_fen` 解析、`parse_ecpm_yuan` ÷100 转元;本列只存原值。
"""
from __future__ import annotations

from datetime import datetime

from sqlalchemy import DateTime, ForeignKey, Integer, String, UniqueConstraint, func
from sqlalchemy.orm import Mapped, mapped_column

from app.db.base import Base


class AdEcpmRecord(Base):
    __tablename__ = "ad_ecpm_record"
    __table_args__ = (
        UniqueConstraint("ad_session_id", name="uq_ad_ecpm_record_session"),
    )

    id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
    user_id: Mapped[int] = mapped_column(
        Integer, ForeignKey("user.id"), index=True, nullable=False
    )
    # 广告类型:reward_video(激励视频) / draw(Draw 信息流) 等;不强行统一代码位,各类型各自上报
    ad_type: Mapped[str] = mapped_column(String(32), nullable=False)
    # 点位场景:comparison(比价) / coupon(领券) / welfare(福利),供收益报表区分比价/领券 Draw 收益;
    # 仅信息流/Draw 上报(比价与领券共用同一代码位,只能客户端各调用点显式打标),激励视频为 NULL。
    feed_scene: Mapped[str | None] = mapped_column(String(16), nullable=True)
    # 客户端生成的一次广告会话 id;激励视频 S2S 回调 extra 会透传同值
    ad_session_id: Mapped[str | None] = mapped_column(String(64), index=True, nullable=True)
    # 实际投放的 ADN(穿山甲 getShowEcpm().getSdkName(),如 pangle / gdt)
    adn: Mapped[str | None] = mapped_column(String(32), nullable=True)
    # 实际展示用的代码位(底层 mediation rit,非客户端配置位)
    slot_id: Mapped[str | None] = mapped_column(String(64), nullable=True)
    # 我们的穿山甲应用环境:prod(傻瓜比价正式应用) / test(测试应用)。客户端按 AdConfig.useProductionApp 上报。
    # 与底层 adn 不同:这是「我们用的是哪个 App」,adn 是「聚合后实际填充的子渠道」。旧数据为 NULL。
    app_env: Mapped[str | None] = mapped_column(String(16), nullable=True)
    # 我们在穿山甲后台配置的代码位 ID(AdConfig.feedCodeId/rewardCodeId 返回的 104xxx,**非** slot_id 的底层 rit)。旧数据为 NULL。
    our_code_id: Mapped[str | None] = mapped_column(String(64), nullable=True)
    # 客户端上报的 eCPM 原始字符串(单位:分/千次展示,SDK getEcpm 原值,原样存)
    ecpm_raw: Mapped[str] = mapped_column(String(32), nullable=False)
    # 北京时间日期串 'YYYY-MM-DD',按它等值做"按天聚合"(不在 SQL 里做跨时区 date 比较)
    report_date: Mapped[str] = mapped_column(String(10), index=True, nullable=False)

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

    def __repr__(self) -> str:  # pragma: no cover
        return (
            f"<AdEcpmRecord user_id={self.user_id} {self.ad_type} "
            f"ecpm={self.ecpm_raw} adn={self.adn}>"
        )
