"""admin 大盘 schemas(对应 stats.dashboard_overview 的嵌套结构)。"""
from __future__ import annotations

from datetime import date

from pydantic import BaseModel


class DashboardUsers(BaseModel):
    total: int
    active: int
    disabled: int
    deleted: int
    new_today: int
    dau: int


class DashboardCoins(BaseModel):
    reward_video_coin_total: int = 0
    reward_video_watch_count: int = 0
    feed_ad_coin_total: int = 0
    feed_ad_watch_count: int = 0
    signin_coin_total: int = 0
    signin_count: int = 0
    signin_boost_coin_total: int = 0
    signin_boost_watch_count: int = 0
    granted_total: int


class DashboardCash(BaseModel):
    withdraw_success_cents: int
    withdraw_pending_count: int
    withdraw_success_count: int
    withdraw_failed_count: int


class DashboardComparison(BaseModel):
    total: int
    success: int
    success_rate: float


class DashboardPeriodUsers(BaseModel):
    new: int
    active: int
    # 次日留存(2026-07-05 起):retained_new_users = 窗口内逐日「前一日新增且当日活跃」用户数之和,
    # retention_cohort = 对应的前一日新增基数之和,retention_rate = 两者之比。
    retained_new_users: int
    retention_cohort: int = 0
    retention_rate: float | None = None
    retention_note: str


class DashboardPeriodComparison(BaseModel):
    total: int
    completed: int
    cancelled: int
    success: int
    success_rate: float | None = None
    ordered: int
    average_duration_ms: int | None = None
    median_duration_ms: int | None = None
    p95_duration_ms: int | None = None
    average_saved_cents: int | None = None
    token_cost_total_yuan: float = 0.0


class DashboardPeriodCoupon(BaseModel):
    """领券核心数据(2026-07-05 产品新增)。点位=一张券(coupon_claim_record 一天一条终态);
    成功口径 success+already_claimed(与「我的」页累计领券一致)。"""

    started: int = 0
    # 全部领成功的次数:completed 且当日该设备全部点位成功
    all_success: int = 0
    success_rate: float | None = None
    # 本期 session 触达的点位中成功的条数(同设备同日去重)
    point_success: int = 0
    # 每次发起的应领点位数(本期完成场实际点位数的众数;无完成场为空)
    points_per_session: int | None = None
    # 点位成功率 = point_success / (started × points_per_session);未跑到的点位计入分母视为失败
    point_success_rate: float | None = None
    # 耗时中位数(仅 completed 的 elapsed_ms,同「领券数据」页口径)
    median_elapsed_ms: int | None = None


class DashboardPeriodCoins(BaseModel):
    granted_total: int
    reward_video_coin_total: int = 0
    feed_ad_coin_total: int = 0
    signin_coin_total: int = 0
    signin_boost_coin_total: int = 0
    task_coin_total: int = 0
    coupon_reward_coin_total: int = 0
    comparison_reward_coin_total: int = 0
    regular_task_coin_total: int = 0


class DashboardPeriodCash(BaseModel):
    withdraw_success_cents: int


class DashboardTrendPoint(BaseModel):
    date: date
    active_users: int
    new_users: int
    comparisons: int


class DashboardPeriod(BaseModel):
    date_from: date
    date_to: date
    users: DashboardPeriodUsers
    comparison: DashboardPeriodComparison
    coupon: DashboardPeriodCoupon = DashboardPeriodCoupon()
    coins: DashboardPeriodCoins
    cash: DashboardPeriodCash
    trend: list[DashboardTrendPoint] = []


class DashboardFeedback(BaseModel):
    new: int


class DashboardCps(BaseModel):
    available: bool
    note: str
    meituan_order_count: int = 0
    meituan_commission_cents: int = 0
    meituan_hit_count: int = 0
    meituan_miss_count: int = 0
    meituan_unknown_rate_count: int = 0
    meituan_hit_rate: float | None = None
    jd_order_count: int = 0
    jd_commission_cents: int = 0
    jd_actual_commission_cents: int = 0
    jd_estimated_commission_cents: int = 0
    jd_invalid_count: int = 0


class DashboardOverview(BaseModel):
    users: DashboardUsers
    coins: DashboardCoins
    cash: DashboardCash
    comparison: DashboardComparison
    period: DashboardPeriod
    feedback: DashboardFeedback
    cps: DashboardCps
