"""数据看板路由"""
from datetime import datetime, timedelta, date
from decimal import Decimal
from fastapi import APIRouter, Depends
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select, func, and_

from app.api.deps import get_db, get_admin_user
from app.core.models.user import User
from app.core.models.order import Order
from app.core.models.customer import Customer
from app.core.models.product import Product
from app.schemas.dashboard import DashboardStats, RevenueTrendItem, OrderStatusItem

router = APIRouter(prefix="/dashboard", tags=["数据看板"])


@router.get("/stats", response_model=DashboardStats, summary="核心统计指标")
async def get_stats(
    db: AsyncSession = Depends(get_db),
    current_user: User = Depends(get_admin_user),
):
    tid = current_user.tenant_id
    today = date.today()
    month_start = today.replace(day=1)

    # 今日营收
    r = await db.execute(
        select(func.coalesce(func.sum(Order.grand_total), 0)).where(
            Order.tenant_id == tid,
            Order.status.in_(["paid", "shipped", "completed"]),
            func.date(Order.created_at) == today,
        )
    )
    revenue_today = r.scalar() or Decimal("0")

    # 本月营收
    r = await db.execute(
        select(func.coalesce(func.sum(Order.grand_total), 0)).where(
            Order.tenant_id == tid,
            Order.status.in_(["paid", "shipped", "completed"]),
            func.date(Order.created_at) >= month_start,
        )
    )
    revenue_month = r.scalar() or Decimal("0")

    # 今日订单数
    r = await db.execute(
        select(func.count()).where(
            Order.tenant_id == tid,
            func.date(Order.created_at) == today,
        )
    )
    orders_today = r.scalar() or 0

    # 待处理订单
    r = await db.execute(
        select(func.count()).where(
            Order.tenant_id == tid,
            Order.status == "pending",
        )
    )
    orders_pending = r.scalar() or 0

    # 总客户数
    r = await db.execute(
        select(func.count()).where(Customer.tenant_id == tid)
    )
    customers_total = r.scalar() or 0

    # 上架商品数
    r = await db.execute(
        select(func.count()).where(
            Product.tenant_id == tid,
            Product.status == "active",
        )
    )
    products_active = r.scalar() or 0

    return DashboardStats(
        revenue_today=revenue_today,
        revenue_month=revenue_month,
        orders_today=orders_today,
        orders_pending=orders_pending,
        customers_total=customers_total,
        products_active=products_active,
    )


@router.get("/trend", response_model=list[RevenueTrendItem], summary="近7日营收趋势")
async def get_trend(
    db: AsyncSession = Depends(get_db),
    current_user: User = Depends(get_admin_user),
):
    tid = current_user.tenant_id
    result = []
    for i in range(6, -1, -1):
        d = date.today() - timedelta(days=i)
        r = await db.execute(
            select(func.coalesce(func.sum(Order.grand_total), 0)).where(
                Order.tenant_id == tid,
                Order.status.in_(["paid", "shipped", "completed"]),
                func.date(Order.created_at) == d,
            )
        )
        revenue = r.scalar() or Decimal("0")
        result.append(RevenueTrendItem(
            date=d.strftime("%m/%d"),
            revenue=revenue,
        ))
    return result


@router.get("/order-status", response_model=list[OrderStatusItem], summary="订单状态分布")
async def get_order_status(
    db: AsyncSession = Depends(get_db),
    current_user: User = Depends(get_admin_user),
):
    tid = current_user.tenant_id
    status_map = [
        ("pending",   "待付款", "#e6a23c"),
        ("paid",      "已付款", "#409eff"),
        ("shipped",   "已发货", "#9c27b0"),
        ("completed", "已完成", "#67c23a"),
        ("cancelled", "已取消", "#f56c6c"),
    ]
    result = []
    for status, label, color in status_map:
        r = await db.execute(
            select(func.count()).where(
                Order.tenant_id == tid,
                Order.status == status,
            )
        )
        count = r.scalar() or 0
        result.append(OrderStatusItem(name=label, value=count, color=color))
    return result
