"""后台财务管理路由 — 充值订单查询 + 手动调账。"""
from fastapi import APIRouter, Depends, HTTPException, Query
from sqlalchemy import or_, select, func
from sqlalchemy.ext.asyncio import AsyncSession

from app.core.deps import require_role
from app.database import get_db
from app.models.balance_log import BalanceChangeType, BalanceLog
from app.models.recharge_order import RechargeOrder, RechargeStatus
from app.models.user import User
from app.schemas.common import ApiResponse
from app.schemas.recharge import RechargeOrderItem

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


@router.get("/recharge-orders", response_model=ApiResponse)
async def list_recharge_orders(
    keyword: str | None = Query(None, description="按订单号/用户名/邮箱搜索"),
    status: str | None = Query(None),
    channel: str | None = Query(None),
    limit: int = Query(50, ge=1, le=200),
    offset: int = Query(0, ge=0),
    db: AsyncSession = Depends(get_db),
    _: User = Depends(_admin),
):
    stmt = (
        select(RechargeOrder)
        .order_by(RechargeOrder.created_at.desc())
        .limit(limit)
        .offset(offset)
    )
    if status:
        stmt = stmt.where(RechargeOrder.status == status)
    if channel:
        stmt = stmt.where(RechargeOrder.channel == channel)
    if keyword:
        like = f"%{keyword}%"
        # 按订单号或关联用户搜索（子查询）
        user_ids_stmt = select(User.id).where(
            or_(User.username.like(like), User.email.like(like), User.phone.like(like))
        )
        stmt = stmt.where(
            or_(
                RechargeOrder.out_trade_no.like(like),
                RechargeOrder.trade_no.like(like),
                RechargeOrder.user_id.in_(user_ids_stmt),
            )
        )
    res = await db.execute(stmt)
    orders = res.scalars().all()

    # 附加用户信息
    result = []
    for o in orders:
        item = RechargeOrderItem.model_validate(o)
        result.append(item)

    return ApiResponse(data=result)


@router.get("/recharge-orders/stats", response_model=ApiResponse)
async def recharge_stats(
    db: AsyncSession = Depends(get_db),
    _: User = Depends(_admin),
):
    """充值统计：总笔数、总金额、今日到账。"""
    from datetime import datetime, timezone, timedelta

    today_start = datetime.now(timezone.utc).replace(hour=0, minute=0, second=0, microsecond=0)

    total_res = await db.execute(
        select(func.count(RechargeOrder.id), func.sum(RechargeOrder.amount_cents))
        .where(RechargeOrder.status == RechargeStatus.PAID)
    )
    total_count, total_cents = total_res.one()

    today_res = await db.execute(
        select(func.count(RechargeOrder.id), func.sum(RechargeOrder.amount_cents))
        .where(
            RechargeOrder.status == RechargeStatus.PAID,
            RechargeOrder.updated_at >= today_start,
        )
    )
    today_count, today_cents = today_res.one()

    pending_res = await db.execute(
        select(func.count(RechargeOrder.id))
        .where(RechargeOrder.status == RechargeStatus.PENDING)
    )
    pending_count = pending_res.scalar()

    return ApiResponse(data={
        "total_paid_count": total_count or 0,
        "total_paid_cents": total_cents or 0,
        "today_paid_count": today_count or 0,
        "today_paid_cents": today_cents or 0,
        "pending_count": pending_count or 0,
    })


@router.get("/balance-logs", response_model=ApiResponse)
async def list_balance_logs(
    user_id: int | None = Query(None),
    change_type: str | None = Query(None),
    limit: int = Query(50, ge=1, le=200),
    offset: int = Query(0, ge=0),
    db: AsyncSession = Depends(get_db),
    _: User = Depends(_admin),
):
    stmt = (
        select(BalanceLog)
        .order_by(BalanceLog.created_at.desc())
        .limit(limit)
        .offset(offset)
    )
    if user_id:
        stmt = stmt.where(BalanceLog.user_id == user_id)
    if change_type:
        stmt = stmt.where(BalanceLog.change_type == change_type)
    res = await db.execute(stmt)
    logs = res.scalars().all()

    result = []
    for log in logs:
        result.append({
            "id": log.id,
            "user_id": log.user_id,
            "change_type": log.change_type.value,
            "delta": log.delta,
            "balance_after": log.balance_after,
            "ref_no": log.ref_no,
            "operator_id": log.operator_id,
            "remark": log.remark,
            "created_at": log.created_at.isoformat(),
        })

    return ApiResponse(data=result)
