"""admin 首页三统计展示配置:列出三指标配置(+ 真实值预览)+ 改某指标(带审计 + 校验)。

每指标可独立选 real/manual/random。计算逻辑见 app/repositories/ops_stat.py。
权限:operator 可改(运营调门面数字),super 恒可。
"""
from __future__ import annotations

from typing import Annotated

from fastapi import APIRouter, Depends, HTTPException, Request

from app.admin.audit import write_audit
from app.admin.deps import AdminDb, get_client_ip, get_current_admin, require_role
from app.admin.schemas.ops_stat_config import (
    OpsStatItemOut,
    OpsStatUpdateRequest,
)
from app.models.admin import AdminUser
from app.repositories import ops_stat

router = APIRouter(
    prefix="/admin/api/dashboard-display",
    tags=["admin-dashboard-display"],
    dependencies=[Depends(get_current_admin)],
)


@router.get("", response_model=list[OpsStatItemOut], summary="首页三统计配置 + 真实值预览")
def list_display(db: AdminDb) -> list[OpsStatItemOut]:
    return [OpsStatItemOut(**item) for item in ops_stat.get_config(db)]


@router.patch(
    "/{metric}", response_model=OpsStatItemOut, summary="改某指标展示配置(带审计)"
)
def update_display(
    metric: str,
    body: OpsStatUpdateRequest,
    request: Request,
    admin: Annotated[AdminUser, Depends(require_role("operator"))],
    db: AdminDb,
) -> OpsStatItemOut:
    try:
        before, after = ops_stat.update_config(
            db,
            metric,
            mode=body.mode,
            manual_value=body.manual_value,
            random_mult_min=body.random_mult_min,
            random_mult_max=body.random_mult_max,
            random_tick_seconds=body.random_tick_seconds,
            random_anchor_minutes=body.random_anchor_minutes,
            random_kind=body.random_kind,
            random_step_min=body.random_step_min,
            random_step_max=body.random_step_max,
            real_offset=body.real_offset,
            allow_decrease=body.allow_decrease,
            random_initial=body.random_initial,
            apply_now=body.apply_now,
            admin_id=admin.id,
            commit=False,
        )
    except ValueError as e:
        raise HTTPException(status_code=400, detail=str(e)) from e

    write_audit(
        db, admin, action="ops_stat_config.set", target_type="ops_stat_config",
        target_id=metric, detail={"before": before, "after": after},
        ip=get_client_ip(request), commit=False,
    )
    db.commit()

    item = next(it for it in ops_stat.get_config(db) if it["metric"] == metric)
    return OpsStatItemOut(**item)
