"""物流轨迹管理 API — Admin
PUT /api/orders/{order_id}/logistics   # 设置/更新物流信息
"""
from datetime import date, timedelta
from typing import Optional
from fastapi import APIRouter, Depends, HTTPException, Query
from pydantic import BaseModel, Field
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession

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.logistics import OrderDeliveryLog

router = APIRouter(prefix="/orders", tags=["物流管理"])


# ── Schemas ────────────────────────────────────────────────────────────────

class SetLogisticsIn(BaseModel):
    carrier: str = Field(..., min_length=1, max_length=50, description="快递公司名称")
    tracking_no: str = Field(..., min_length=1, max_length=100, description="运单号")
    estimated_delivery: Optional[str] = Field(None, description="预计送达日期 YYYY-MM-DD")


class LogisticsInfoOut(BaseModel):
    order_id: int
    order_no: str
    carrier: Optional[str] = None
    tracking_no: Optional[str] = None
    estimated_delivery: Optional[str] = None
    status: str

    model_config = {"from_attributes": True}


# ── 快递公司列表 ────────────────────────────────────────────────────────────

VALID_CARRIERS = [
    "顺丰速运", "中通快递", "圆通速递", "韵达快递",
    "京东物流", "邮政EMS", "极兔速递", "德邦快递",
]


# ── 路由 ───────────────────────────────────────────────────────────────────

@router.put("/{order_id}/logistics", summary="设置/更新订单物流信息（发货）")
async def set_logistics(
    order_id: int,
    body: SetLogisticsIn,
    db: AsyncSession = Depends(get_db),
    current_user: User = Depends(get_admin_user),
):
    """Admin 给订单填写快递信息，同时将订单状态改为 shipped"""
    # 查订单
    r = await db.execute(
        select(Order).where(
            Order.id == order_id,
            Order.tenant_id == current_user.tenant_id,
        )
    )
    order = r.scalar_one_or_none()
    if not order:
        raise HTTPException(status_code=404, detail="订单不存在")

    if body.carrier not in VALID_CARRIERS:
        raise HTTPException(status_code=400, detail=f"无效快递公司，可选: {VALID_CARRIERS}")

    # 更新订单物流字段
    order.carrier = body.carrier
    order.tracking_no = body.tracking_no
    if body.estimated_delivery:
        order.estimated_delivery = date.fromisoformat(body.estimated_delivery)
    elif body.estimated_delivery is None and order.status == "paid":
        # 默认：paid→shipped 时自动设置预计到达 = 今天+3天
        order.estimated_delivery = date.today() + timedelta(days=3)

    # 记录初始轨迹：已揽收
    from datetime import datetime
    initial_log = OrderDeliveryLog(
        order_id=order.id,
        order_no=order.order_no,
        tenant_id=order.tenant_id,
        carrier=body.carrier,
        tracking_no=body.tracking_no,
        status="PICKED_UP",
        location="揽收网点",
        description="快件已揽收，等待发出",
        event_time=datetime.now(),
    )
    db.add(initial_log)

    # 更新状态：paid→shipped（只有 pending/paid 能发货）
    if order.status in ("pending", "paid"):
        order.status = "shipped"
    # 其他状态（cancelled/completed）不能改

    await db.commit()

    return {
        "ok": True,
        "order_id": order.id,
        "order_no": order.order_no,
        "carrier": body.carrier,
        "tracking_no": body.tracking_no,
        "status": order.status,
        "estimated_delivery": str(order.estimated_delivery) if order.estimated_delivery else None,
    }


@router.get("/{order_id}/logistics", response_model=LogisticsInfoOut, summary="查看订单物流信息")
async def get_logistics_info(
    order_id: int,
    db: AsyncSession = Depends(get_db),
    current_user: User = Depends(get_admin_user),
):
    """Admin 查看订单物流信息"""
    r = await db.execute(
        select(Order).where(
            Order.id == order_id,
            Order.tenant_id == current_user.tenant_id,
        )
    )
    order = r.scalar_one_or_none()
    if not order:
        raise HTTPException(status_code=404, detail="订单不存在")

    return LogisticsInfoOut(
        order_id=order.id,
        order_no=order.order_no,
        carrier=getattr(order, "carrier", None),
        tracking_no=getattr(order, "tracking_no", None),
        estimated_delivery=str(order.estimated_delivery) if getattr(order, "estimated_delivery", None) else None,
        status=order.status,
    )