from app.services.audit import log_audit
"""订单管理路由"""
from typing import Optional
from decimal import Decimal
from fastapi import APIRouter, Depends, HTTPException, Query
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select, func, or_

from app.api.deps import get_db, get_admin_user
from app.core.models.user import User
from app.core.models.order import Order, OrderItem
from app.core.models.customer import Customer
from app.schemas.common import PageResult
from app.schemas.order import OrderOut, OrderDetailOut, OrderStatusUpdate, OrderItemOut

router = APIRouter(prefix="/orders", tags=["订单管理"])


@router.get("", response_model=PageResult[OrderOut], summary="订单列表")
async def list_orders(
    page: int = Query(1, ge=1),
    page_size: int = Query(10, ge=1, le=100),
    keyword: Optional[str] = None,
    status: Optional[str] = None,
    db: AsyncSession = Depends(get_db),
    current_user: User = Depends(get_admin_user),
):
    tid = current_user.tenant_id
    q = select(Order).where(Order.tenant_id == tid)

    if keyword:
        q = q.where(Order.order_no.ilike(f"%{keyword}%"))
    if status:
        q = q.where(Order.status == status)

    total_r = await db.execute(select(func.count()).select_from(q.subquery()))
    total = total_r.scalar() or 0

    q = q.order_by(Order.created_at.desc()).offset((page - 1) * page_size).limit(page_size)
    result = await db.execute(q)
    orders = result.scalars().all()

    items = []
    for o in orders:
        name = ""
        if o.customer_id:
            cr = await db.execute(select(Customer.name).where(Customer.id == o.customer_id))
            name = cr.scalar_one_or_none() or ""
        # Count items from OrderItem
        cnt_r = await db.execute(
            select(func.count(OrderItem.id)).where(OrderItem.order_id == o.id)
        )
        cnt = cnt_r.scalar() or 0
        items.append(OrderOut(
            id=o.id,
            order_no=o.order_no,
            status=o.status,
            grand_total=o.grand_total,
            items_count=cnt,
            customer_name=name,
            created_at=o.created_at,
        ))

    return PageResult(items=items, total=total, page=page, page_size=page_size)


@router.get("/{order_id}", response_model=OrderDetailOut, summary="订单详情")
async def get_order(
    order_id: int,
    db: AsyncSession = Depends(get_db),
    current_user: User = Depends(get_admin_user),
):
    r = await db.execute(
        select(Order).where(
            Order.id == order_id,
            Order.tenant_id == current_user.tenant_id,
        )
    )
    o = r.scalar_one_or_none()
    if not o:
        raise HTTPException(404, "订单不存在")

    customer_name = ""
    if o.customer_id:
        cr = await db.execute(select(Customer.name).where(Customer.id == o.customer_id))
        customer_name = cr.scalar_one_or_none() or ""

    ir = await db.execute(select(OrderItem).where(OrderItem.order_id == order_id))
    raw_items = ir.scalars().all()
    items = []
    for item in raw_items:
        snap = item.product_snapshot or {}
        items.append(OrderItemOut(
            id=item.id,
            product_id=item.product_id,
            product_name=snap.get("name", ""),
            sku=snap.get("sku", ""),
            qty=item.quantity,
            unit_price=item.unit_price,
            subtotal=item.total_price,
            variant_id=snap.get("variant_id"),
            variant_attrs=snap.get("variant_attrs"),
        ))

    return OrderDetailOut(
        id=o.id,
        order_no=o.order_no,
        status=o.status,
        grand_total=o.grand_total,
        subtotal=o.subtotal or o.grand_total,
        shipping_fee=o.shipping_total or Decimal("0"),
        discount_amount=o.discount_total or Decimal("0"),
        items_count=len(items),
        customer_name=customer_name,
        shipping_address=o.shipping_address,
        remark=o.note,
        created_at=o.created_at,
        items=items,
    )


@router.put("/{order_id}/status", summary="更新订单状态")
async def update_order_status(
    order_id: int,
    body: OrderStatusUpdate,
    db: AsyncSession = Depends(get_db),
    current_user: User = Depends(get_admin_user),
):
    valid = {"pending", "paid", "shipped", "completed", "cancelled"}
    if body.status not in valid:
        raise HTTPException(400, f"无效状态，可选: {valid}")

    r = await db.execute(
        select(Order).where(
            Order.id == order_id,
            Order.tenant_id == current_user.tenant_id,
        )
    )
    o = r.scalar_one_or_none()
    if not o:
        raise HTTPException(404, "订单不存在")

    old_status = o.status
    o.status = body.status
    await db.commit()

    await log_audit(
        db=db,
        tenant_id=current_user.tenant_id,
        action=f"orders.status_change",
        actor_type="admin",
        actor_id=current_user.id,
        actor_name=current_user.profile.get("name") if current_user.profile else None,
        target_type="orders",
        target_id=o.id,
        target_name=o.order_no,
        changes={"status": [old_status, body.status]},
    )

    # ── 邮件通知（从 TenantSettings 读取 SMTP 配置）───────────────
    #     from app.services.email import send_email, build_smtp_config
    #     from app.core.models.tenant_settings import TenantSettings
    #     settings_result = await db.execute(
    #         select(TenantSettings).where(TenantSettings.tenant_id == o.tenant_id)
    #     )
    #     settings_obj = settings_result.scalar_one_or_none()
    #     smtp_config = build_smtp_config(settings_obj)
    #     if body.status in ("paid", "shipped", "completed") and smtp_config.get("enabled"):
    #         cr = await db.execute(select(Customer).where(Customer.id == o.customer_id))
    #         cust = cr.scalar_one_or_none()
    #         if cust and cust.email:
    #             status_map = {"paid": "已付款", "shipped": "已发货", "completed": "已完成"}
    #             await send_email(
    #                 to=cust.email,
    #                 subject=f"订单状态更新 {o.order_no}",
    #                 html_body=f"<html><body><p>您的订单 {o.order_no} 已更新状态为：<strong>{status_map.get(body.status, body.status)}</strong></p></body></html>",
    #                 smtp_config=smtp_config,
    #             )


    return {"ok": True}