"""后台仪表盘真实统计。"""
from datetime import datetime, timezone
from zoneinfo import ZoneInfo

from fastapi import APIRouter, Depends
from sqlalchemy import func, select
from sqlalchemy.ext.asyncio import AsyncSession

from app.core.deps import require_role
from app.database import get_db
from app.models.cloud_server import CloudServer, CloudServerStatus
from app.models.order import Order, OrderStatus
from app.models.product import Product, ProductStatus
from app.models.recharge_order import RechargeOrder, RechargeStatus
from app.models.upstream_action_log import UpstreamActionLog
from app.models.user import User
from app.schemas.common import ApiResponse

router = APIRouter()
_admin = require_role("admin", "super_admin")


def _enum_value(value) -> str:
    return value.value if hasattr(value, "value") else str(value)


def _percent(done: int, total: int) -> int:
    if total <= 0:
        return 0
    return max(0, min(100, round(done * 100 / total)))


def _fmt_cny(cents: int) -> str:
    return f"¥{cents / 100:.2f}"


def _iso(value: datetime | None) -> str | None:
    return value.isoformat() if value else None


def _today_start_utc() -> datetime:
    local_tz = ZoneInfo("Asia/Shanghai")
    now = datetime.now(local_tz)
    today_local = now.replace(hour=0, minute=0, second=0, microsecond=0)
    return today_local.astimezone(timezone.utc)


async def _scalar_int(db: AsyncSession, stmt) -> int:
    return int((await db.execute(stmt)).scalar() or 0)


async def _recent_events(db: AsyncSession) -> list[dict]:
    events: list[dict] = []

    user_res = await db.execute(select(User).order_by(User.id.desc()).limit(5))
    for user in user_res.scalars().all():
        display = user.nickname or user.username or f"用户 #{user.id}"
        events.append({
            "key": f"user-{user.id}",
            "type": "用户",
            "action": f"{display} 注册",
            "status": _enum_value(user.status),
            "time": _iso(user.created_at),
        })

    recharge_res = await db.execute(
        select(RechargeOrder)
        .where(RechargeOrder.status == RechargeStatus.PAID)
        .order_by(RechargeOrder.updated_at.desc(), RechargeOrder.id.desc())
        .limit(5)
    )
    for order in recharge_res.scalars().all():
        events.append({
            "key": f"recharge-{order.id}",
            "type": "财务",
            "action": f"充值到账 {order.out_trade_no} {_fmt_cny(order.amount_cents)}",
            "status": _enum_value(order.status),
            "time": _iso(order.updated_at or order.created_at),
        })

    order_res = await db.execute(select(Order).order_by(Order.id.desc()).limit(5))
    for order in order_res.scalars().all():
        paid_amount = max(0, int(order.total_amount or 0) - int(order.discount_amount or 0))
        events.append({
            "key": f"order-{order.id}",
            "type": "订单",
            "action": f"服务订单 {order.out_order_no} {_fmt_cny(paid_amount)}",
            "status": _enum_value(order.status),
            "time": _iso(order.created_at),
        })

    action_res = await db.execute(select(UpstreamActionLog).order_by(UpstreamActionLog.id.desc()).limit(5))
    for action in action_res.scalars().all():
        events.append({
            "key": f"resource-{action.id}",
            "type": "资源",
            "action": f"{action.action_type} #{action.id}",
            "status": action.status,
            "time": _iso(action.updated_at or action.created_at),
        })

    events.sort(key=lambda item: item.get("time") or "", reverse=True)
    return events[:8]


@router.get("", response_model=ApiResponse)
async def get_admin_dashboard(
    db: AsyncSession = Depends(get_db),
    _: User = Depends(_admin),
):
    today_start = _today_start_utc()

    user_total = await _scalar_int(db, select(func.count(User.id)))
    today_income_cents = await _scalar_int(
        db,
        select(func.coalesce(func.sum(RechargeOrder.amount_cents), 0)).where(
            RechargeOrder.status == RechargeStatus.PAID,
            RechargeOrder.updated_at >= today_start,
        ),
    )
    product_total = await _scalar_int(db, select(func.count(Product.id)))
    product_active = await _scalar_int(
        db,
        select(func.count(Product.id)).where(Product.status == ProductStatus.ACTIVE.value),
    )
    cloud_total = await _scalar_int(db, select(func.count(CloudServer.id)))
    cloud_enabled = await _scalar_int(db, select(func.count(CloudServer.id)).where(CloudServer.disabled.is_(False)))
    cloud_online = await _scalar_int(
        db,
        select(func.count(CloudServer.id)).where(
            CloudServer.disabled.is_(False),
            CloudServer.status == CloudServerStatus.ONLINE.value,
        ),
    )

    order_total = await _scalar_int(db, select(func.count(Order.id)))
    order_handled = await _scalar_int(
        db,
        select(func.count(Order.id)).where(Order.status != OrderStatus.PENDING),
    )
    recharge_total = await _scalar_int(db, select(func.count(RechargeOrder.id)))
    recharge_reconciled = await _scalar_int(
        db,
        select(func.count(RechargeOrder.id)).where(RechargeOrder.status != RechargeStatus.PENDING),
    )

    pending_orders = await _scalar_int(db, select(func.count(Order.id)).where(Order.status == OrderStatus.PENDING))
    pending_recharges = await _scalar_int(
        db,
        select(func.count(RechargeOrder.id)).where(RechargeOrder.status == RechargeStatus.PENDING),
    )
    failed_resource_actions = await _scalar_int(
        db,
        select(func.count(UpstreamActionLog.id)).where(UpstreamActionLog.status == "failed"),
    )

    return ApiResponse(data={
        "stats": {
            "users_total": user_total,
            "today_income_cents": today_income_cents,
            "products_total": product_total,
            "products_active": product_active,
            "cloud_nodes_total": cloud_total,
            "cloud_nodes_online": cloud_online,
            "cloud_nodes_enabled": cloud_enabled,
        },
        "overview": {
            "order_processing_percent": _percent(order_handled, order_total),
            "cloud_connectivity_percent": _percent(cloud_online, cloud_enabled),
            "finance_reconcile_percent": _percent(recharge_reconciled, recharge_total),
            "pending_orders": pending_orders,
            "pending_recharges": pending_recharges,
            "failed_resource_actions": failed_resource_actions,
        },
        "recent_events": await _recent_events(db),
    })
