"""advanced_order_editor admin routes (mounted under /api/admin by init_plugin).

- PUT  /orders/{order_id}/advanced         高级编辑：重算总额 + 写 adjustments / advanced_edited
- POST /orders/{order_id}/advanced-adjust  差额结算（topup 补款 / refund 退款）

两路由共用守卫：require_permission("orders.advanced_edit") + require_plugin。
写入路径复用 orders.py 的 _apply_order_edit / _apply_inventory_for_order_edit，
结算路径复用 services.apply_advanced_adjust —— 不在此重复实现任何业务逻辑。
"""
from typing import Optional

from fastapi import APIRouter, Depends
from sqlalchemy.ext.asyncio import AsyncSession

from app.api.deps import get_db, require_permission
from app.api.routers.orders import OrderEditBody, _apply_order_edit
from app.core.models.user import User
from app.core.services.plugin_helper import require_plugin
from app.plugins.advanced_order_editor.schemas import (
    AdvancedAdjustBody,
    AdvancedAdjustOut,
    AdvancedEditBody,
)
from app.plugins.advanced_order_editor.services import apply_advanced_adjust

router = APIRouter(tags=["advanced_order_editor"])


async def _require_advanced_editor(
    user: User = Depends(require_permission("orders.advanced_edit")),
    db: AsyncSession = Depends(get_db),
) -> User:
    """双守卫：权限不足 403；插件未启用 503（租户粒度）。"""
    await require_plugin("advanced_order_editor", db, user.tenant_id)
    return user


def _actor_name(user: User) -> Optional[str]:
    return (
        user.profile.get("name") if isinstance(user.profile, dict)
        else (user.profile if isinstance(user.profile, str) else None)
    )


@router.put("/orders/{order_id}/advanced", summary="高级编辑订单")
async def advanced_edit(
    order_id: int,
    body: AdvancedEditBody,
    db: AsyncSession = Depends(get_db),
    user: User = Depends(_require_advanced_editor),
):
    """与 PUT /orders/{id} 同一写入路径，advanced=True：
    重算 grand_total（含 adjustments）、写入 extra_attributes["adjustments"]，
    并置写一次性的 advanced_edited 标记。

    spec line 22: 订单已发货 / 已完成 / 退款中 / 已退款 → 拒绝 item/amount
    编辑（这些状态下金额已记账，改了会与在途/已完成账目冲突）。该守卫
    在 orders._apply_order_edit 内 locked read 之后做（消除 unlocked
    select 与 locked select 之间的 TOCTOU 竞态）；404 由 load_admin_order
    抛。
    """
    await _apply_order_edit(
        db, user.tenant_id, order_id,
        OrderEditBody(
            status=body.status,
            note=body.note,
            carrier=body.carrier,
            tracking_no=body.tracking_no,
            estimated_delivery=body.estimated_delivery,
            shipping_address=body.shipping_address,
            items=body.items,
            adjustments=[a.model_dump(mode="json") for a in body.adjustments],
        ),
        actor_id=user.id,
        actor_name=_actor_name(user),
        advanced=True,
    )
    return {"ok": True}


@router.post("/orders/{order_id}/advanced-adjust",
             response_model=AdvancedAdjustOut, summary="差额结算（补款 / 退款）")
async def advanced_adjust(
    order_id: int,
    body: AdvancedAdjustBody,
    db: AsyncSession = Depends(get_db),
    user: User = Depends(_require_advanced_editor),
):
    return await apply_advanced_adjust(
        db, user.tenant_id, order_id, body,
        actor_id=user.id, actor_name=_actor_name(user),
    )
