"""库存状态管理 Admin API

路由：
  GET    /admin/stock-statuses          列表
  POST   /admin/stock-statuses          新建自定义状态
  PUT    /admin/stock-statuses/{id}     编辑
  DELETE /admin/stock-statuses/{id}     删除（系统预置禁止）
"""
from typing import List

from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy import select, func
from sqlalchemy.ext.asyncio import AsyncSession

from app.api.deps import get_db, get_admin_user
from app.core.models.stock_status import StockStatus
from app.core.models.product import Product
from app.core.models.user import User
from app.schemas.stock_status import StockStatusIn, StockStatusUpdate, StockStatusOut

router = APIRouter(prefix="/admin/stock-statuses", tags=["库存状态管理"])


@router.get("", response_model=List[StockStatusOut], summary="库存状态列表")
async def list_stock_statuses(
    db: AsyncSession = Depends(get_db),
    admin: User = Depends(get_admin_user),
):
    result = await db.execute(
        select(StockStatus)
        .where(StockStatus.tenant_id == admin.tenant_id)
        .order_by(StockStatus.sort_order, StockStatus.id)
    )
    rows = result.scalars().all()
    return [StockStatusOut.model_validate(r) for r in rows]


@router.post("", response_model=StockStatusOut, status_code=201, summary="新建库存状态")
async def create_stock_status(
    body: StockStatusIn,
    db: AsyncSession = Depends(get_db),
    admin: User = Depends(get_admin_user),
):
    existing = await db.execute(
        select(StockStatus).where(
            StockStatus.tenant_id == admin.tenant_id,
            StockStatus.slug == body.slug,
        )
    )
    if existing.scalar_one_or_none():
        raise HTTPException(status_code=409, detail=f"slug '{body.slug}' 已存在")

    if body.is_default:
        await _clear_default(db, admin.tenant_id)

    if body.is_type_default:
        await _clear_type_default(db, admin.tenant_id, body.status_type)

    obj = StockStatus(
        tenant_id=admin.tenant_id,
        name=body.name,
        name_en=body.name_en,
        slug=body.slug,
        allow_purchase=int(body.allow_purchase),
        badge_color=body.badge_color,
        badge_text=body.badge_text,
        badge_text_en=body.badge_text_en,
        sort_order=body.sort_order,
        is_default=int(body.is_default),
        is_system=0,
        status_type=body.status_type,
        is_type_default=int(body.is_type_default),
    )
    db.add(obj)
    await db.commit()
    await db.refresh(obj)
    return StockStatusOut.model_validate(obj)


@router.put("/{status_id}", response_model=StockStatusOut, summary="编辑库存状态")
async def update_stock_status(
    status_id: int,
    body: StockStatusUpdate,
    db: AsyncSession = Depends(get_db),
    admin: User = Depends(get_admin_user),
):
    obj = await _get_or_404(db, admin.tenant_id, status_id)

    if body.slug is not None and obj.is_system:
        raise HTTPException(status_code=400, detail="系统预置状态不可修改 slug")

    if body.slug is not None and body.slug != obj.slug:
        dup = await db.execute(
            select(StockStatus).where(
                StockStatus.tenant_id == admin.tenant_id,
                StockStatus.slug == body.slug,
            )
        )
        if dup.scalar_one_or_none():
            raise HTTPException(status_code=409, detail=f"slug '{body.slug}' 已存在")

    if body.is_default:
        await _clear_default(db, admin.tenant_id)

    target_type = body.status_type if body.status_type is not None else obj.status_type
    if body.is_type_default:
        await _clear_type_default(db, admin.tenant_id, target_type)

    for field in ("name", "name_en", "slug", "badge_color", "badge_text", "badge_text_en", "sort_order"):
        val = getattr(body, field, None)
        if val is not None:
            setattr(obj, field, val)
    if body.allow_purchase is not None:
        obj.allow_purchase = int(body.allow_purchase)
    if body.is_default is not None:
        obj.is_default = int(body.is_default)
    if body.status_type is not None:
        obj.status_type = body.status_type
    if body.is_type_default is not None:
        obj.is_type_default = int(body.is_type_default)

    await db.commit()
    await db.refresh(obj)
    return StockStatusOut.model_validate(obj)


@router.delete("/{status_id}", summary="删除库存状态")
async def delete_stock_status(
    status_id: int,
    db: AsyncSession = Depends(get_db),
    admin: User = Depends(get_admin_user),
):
    obj = await _get_or_404(db, admin.tenant_id, status_id)
    if obj.is_system:
        raise HTTPException(status_code=400, detail="系统预置状态不可删除")

    ref_count = (await db.execute(
        select(func.count()).select_from(Product).where(
            Product.tenant_id == admin.tenant_id,
            Product.stock_status_id == status_id,
        )
    )).scalar() or 0
    if ref_count:
        raise HTTPException(status_code=409, detail=f"有 {ref_count} 个商品使用此状态，请先更换后再删除")

    await db.delete(obj)
    await db.commit()
    return {"detail": "已删除"}


async def _get_or_404(db: AsyncSession, tenant_id: int, status_id: int) -> StockStatus:
    result = await db.execute(
        select(StockStatus).where(
            StockStatus.id == status_id,
            StockStatus.tenant_id == tenant_id,
        )
    )
    obj = result.scalar_one_or_none()
    if not obj:
        raise HTTPException(status_code=404, detail="库存状态不存在")
    return obj


async def _clear_default(db: AsyncSession, tenant_id: int) -> None:
    result = await db.execute(
        select(StockStatus).where(
            StockStatus.tenant_id == tenant_id,
            StockStatus.is_default == 1,
        )
    )
    for s in result.scalars().all():
        s.is_default = 0


async def _clear_type_default(db: AsyncSession, tenant_id: int, status_type: str) -> None:
    result = await db.execute(
        select(StockStatus).where(
            StockStatus.tenant_id == tenant_id,
            StockStatus.status_type == status_type,
            StockStatus.is_type_default == 1,
        )
    )
    for s in result.scalars().all():
        s.is_type_default = 0
