"""admin 广告收益报表:按 用户/日期/广告类型/应用/代码位 聚合 展示条数 / 收益 / 金币。

任意已登录 admin 可看(只读,不涉及资金操作)。聚合逻辑在 app/admin/repositories/ad_revenue.py。
"""
from __future__ import annotations

from datetime import date as _date
from typing import Annotated

from fastapi import APIRouter, Depends, HTTPException, Query

from app.admin.deps import AdminDb, get_current_admin
from app.admin.repositories import ad_revenue
from app.admin.schemas.ad_revenue import (
    AdRevenueDaily,
    AdRevenueHourly,
    AdRevenueReportOut,
    AdRevenueRow,
    AdRevenueTypeStat,
)
from app.core.rewards import cn_today

router = APIRouter(
    prefix="/admin/api/ad-revenue-report",
    tags=["admin-ad-revenue-report"],
    dependencies=[Depends(get_current_admin)],
)

# 区间最大跨度(天);超出拒绝,避免审计页一次拉过多天(逐日审计 + 大查询)拖垮接口。
_MAX_RANGE_DAYS = 92


def _parse_day(value: str | None, *, field: str, default: _date) -> _date:
    if value is None:
        return default
    try:
        return _date.fromisoformat(value)
    except ValueError as e:
        raise HTTPException(status_code=422, detail=f"{field} 需为 YYYY-MM-DD") from e


@router.get("", response_model=AdRevenueReportOut, summary="广告收益报表(按 日期区间/用户/类型/应用/代码位 聚合)")
def get_ad_revenue_report(
    db: AdminDb,
    date_from: Annotated[str | None, Query(description="起始日 北京时间 YYYY-MM-DD,默认今天")] = None,
    date_to: Annotated[str | None, Query(description="结束日 北京时间 YYYY-MM-DD,闭区间,默认=date_from")] = None,
    user_id: Annotated[int | None, Query(description="只看某用户;不传=全部用户")] = None,
    ad_type: Annotated[
        str | None,
        Query(description="reward_video / feed / draw;不传=全部类型"),
    ] = None,
    feed_scene: Annotated[
        str | None,
        Query(
            description="comparison(比价) / coupon(领券) / welfare(福利);不传=全部场景。"
            "全局筛选,同时影响明细 / 合计 / 趋势"
        ),
    ] = None,
    granularity: Annotated[
        str, Query(description="day=按天 / hour=按小时(北京时间);区间>1 天建议用 day")
    ] = "day",
    limit: Annotated[int, Query(ge=1, le=1000, description="每页条数(分页大小)")] = 500,
    offset: Annotated[int, Query(ge=0, description="分页偏移(已跳过的条数)=(页码-1)×每页条数")] = 0,
    sort: Annotated[
        str, Query(description="排序:time=时间倒序(默认) / ecpm=按 eCPM 数值倒序")
    ] = "time",
) -> AdRevenueReportOut:
    today = cn_today()
    d_from = _parse_day(date_from, field="date_from", default=today)
    d_to = _parse_day(date_to, field="date_to", default=d_from)
    if d_to < d_from:
        raise HTTPException(status_code=422, detail="date_to 不能早于 date_from")
    if (d_to - d_from).days + 1 > _MAX_RANGE_DAYS:
        raise HTTPException(status_code=422, detail=f"区间最长 {_MAX_RANGE_DAYS} 天")

    result = ad_revenue.ad_revenue_report(
        db, date_from=d_from.isoformat(), date_to=d_to.isoformat(),
        user_id=user_id, ad_type=ad_type, feed_scene=feed_scene,
        granularity=granularity, limit=limit, offset=offset, sort=sort,
    )
    return AdRevenueReportOut(
        date_from=d_from.isoformat(),
        date_to=d_to.isoformat(),
        daily=[AdRevenueDaily(**d) for d in result["daily"]],
        hourly=[AdRevenueHourly(**h) for h in result["hourly"]],
        type_stats={k: AdRevenueTypeStat(**v) for k, v in result["type_stats"].items()},
        dau=result["dau"],
        total=result["total"],
        truncated=result["truncated"],
        total_impressions=result["total_impressions"],
        total_revenue_yuan=result["total_revenue_yuan"],
        total_expected_coin=result["total_expected_coin"],
        total_actual_coin=result["total_actual_coin"],
        mismatch_count=result["mismatch_count"],
        items=[AdRevenueRow(**r) for r in result["items"]],
    )
