"""首页三统计展示配置表(帮助用户 / 完成比价 / 累计节省)。

客户端首页顶部三个门面数字,每个指标可独立选 3 种展示模式(运营后台配):
  - real   : 实时查真实数据(help_users=去重成功比价用户数 / total_compares=成功比价数 /
             total_saved=成功比价省额求和)。
  - manual : 直接用运营手填的固定值。
  - random : 「只增不减」的伪增长——读取时惰性 tick:距上次 tick 超过 random_tick_seconds
             就把 random_current 乘以一个 [min,max] 内的随机倍率(倍率恒 ≥1.0 → 只增不减)。

数值单位约定(三指标都用各自「基础单位」的整数存,避免浮点):
  - help_users / total_compares : 个数(人 / 次)
  - total_saved                 : 分(cents);客户端 ÷100 显示「元」

倍率用千分比整数存:1.000→1000、1.100→1100,读时 factor = randint(min,max)/1000。

一行一指标,主键 = metric。初始由 migration 播种 3 行(默认 manual + 当前写死门面值,
保证上线无视觉变化),运营再按需切模式。
"""
from __future__ import annotations

from datetime import datetime

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

from app.db.base import Base


class OpsStatConfig(Base):
    __tablename__ = "ops_stat_config"

    # help_users / total_compares / total_saved
    metric: Mapped[str] = mapped_column(String(32), primary_key=True)
    # real / manual / random(每指标独立)
    mode: Mapped[str] = mapped_column(String(16), nullable=False, default="real")

    # manual 模式固定值(基础单位整数;total_saved 为分)
    manual_value: Mapped[int | None] = mapped_column(Integer, nullable=True)

    # random 模式:倍率区间(千分比,≥1000 保证只增不减)+ tick 周期 + 当前值 + 上次 tick 时刻
    random_mult_min: Mapped[int] = mapped_column(Integer, nullable=False, default=1000)
    random_mult_max: Mapped[int] = mapped_column(Integer, nullable=False, default=1100)
    random_tick_seconds: Mapped[int] = mapped_column(Integer, nullable=False, default=86400)
    # 触发时刻对齐偏移:距北京时间 0 点的分钟数。按单位:天=每日时刻(h*60+m)、小时=每小时第几分、
    # 分钟=0。刷新在北京时间 (anchor + k*interval) 的钟点边界触发(见 repo _refresh)。
    random_anchor_minutes: Mapped[int] = mapped_column(Integer, nullable=False, default=0)
    random_current: Mapped[int | None] = mapped_column(Integer, nullable=True)
    random_last_tick_at: Mapped[datetime | None] = mapped_column(
        DateTime(timezone=True), nullable=True
    )

    # random 增长方式:mult=×倍率(用 random_mult_*) / add=+绝对增量(用 random_step_*,基础单位整数)
    random_kind: Mapped[str] = mapped_column(String(8), nullable=False, default="mult")
    random_step_min: Mapped[int] = mapped_column(Integer, nullable=False, default=0)
    random_step_max: Mapped[int] = mapped_column(Integer, nullable=False, default=0)
    # real 模式保底值(基础单位;total_saved 为分):展示值 = max(真实值, 保底值)。冷启动显示保底撑
    # 场面,真实值涨过保底后显示纯真实、零差距。列名沿用 real_offset(语义已从"偏移"改为"保底")
    real_offset: Mapped[int] = mapped_column(Integer, nullable=False, default=0)
    # 门面数字默认「只增不减」;运营明确要下调时才开此开关(real/manual 刷新都受护栏约束)
    allow_decrease: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False)

    updated_by_admin_id: Mapped[int | None] = mapped_column(Integer, nullable=True)
    updated_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"<OpsStatConfig metric={self.metric} mode={self.mode}>"
