# backend/app/plugins/unit_split/router.py
from fastapi import APIRouter, Depends, HTTPException
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.services.plugin_helper import require_plugin
from app.plugins.unit_split.models import ProductUnitDict, ProductSellingUnit
from app.plugins.unit_split.schemas import UnitDictIn, UnitDictOut, SellingUnitIn, SellingUnitOut


async def _require_unit_split(db: AsyncSession = Depends(get_db)) -> None:
    """插件停用时返回 503，前端据此隐藏功能区域"""
    await require_plugin("unit_split", db)


router = APIRouter(tags=["unit_split"], dependencies=[Depends(_require_unit_split)])


# ── 全局单位词典 ──────────────────────────────────────────────

@router.get("/unit-split/dict", response_model=list[UnitDictOut])
async def list_unit_dict(
    db: AsyncSession = Depends(get_db),
    user: User = Depends(get_admin_user),
):
    r = await db.execute(
        select(ProductUnitDict)
        .where(ProductUnitDict.tenant_id == user.tenant_id)
        .order_by(ProductUnitDict.is_system.desc(), ProductUnitDict.id)
    )
    return r.scalars().all()


@router.post("/unit-split/dict", response_model=UnitDictOut, status_code=201)
async def create_unit_dict(
    body: UnitDictIn,
    db: AsyncSession = Depends(get_db),
    user: User = Depends(get_admin_user),
):
    entry = ProductUnitDict(
        tenant_id=user.tenant_id,
        unit_name=body.unit_name,
        unit_name_en=body.unit_name_en,
        is_system=0,
    )
    db.add(entry)
    await db.commit()
    await db.refresh(entry)
    return entry


@router.put("/unit-split/dict/{dict_id}", response_model=UnitDictOut)
async def update_unit_dict(
    dict_id: int,
    body: UnitDictIn,
    db: AsyncSession = Depends(get_db),
    user: User = Depends(get_admin_user),
):
    r = await db.execute(
        select(ProductUnitDict).where(
            ProductUnitDict.id == dict_id,
            ProductUnitDict.tenant_id == user.tenant_id,
        )
    )
    entry = r.scalar_one_or_none()
    if entry is None:
        raise HTTPException(status_code=404, detail="词条不存在")
    if entry.is_system:
        raise HTTPException(status_code=400, detail="内置词条不可修改")
    entry.unit_name = body.unit_name
    entry.unit_name_en = body.unit_name_en
    await db.commit()
    await db.refresh(entry)
    return entry


@router.delete("/unit-split/dict/{dict_id}", status_code=204)
async def delete_unit_dict(
    dict_id: int,
    db: AsyncSession = Depends(get_db),
    user: User = Depends(get_admin_user),
):
    r = await db.execute(
        select(ProductUnitDict).where(
            ProductUnitDict.id == dict_id,
            ProductUnitDict.tenant_id == user.tenant_id,
        )
    )
    entry = r.scalar_one_or_none()
    if entry is None:
        raise HTTPException(status_code=404, detail="词条不存在")
    if entry.is_system:
        raise HTTPException(status_code=400, detail="内置词条不可删除")
    await db.delete(entry)
    await db.commit()


# ── 商品销售单位 ──────────────────────────────────────────────

@router.get("/unit-split/products/{product_id}/units", response_model=list[SellingUnitOut])
async def list_product_units(
    product_id: int,
    db: AsyncSession = Depends(get_db),
    user: User = Depends(get_admin_user),
):
    from app.core.models.product import Product
    prod_r = await db.execute(
        select(Product).where(Product.id == product_id, Product.tenant_id == user.tenant_id)
    )
    product = prod_r.scalar_one_or_none()
    if product is None:
        raise HTTPException(status_code=404, detail="商品不存在")

    r = await db.execute(
        select(ProductSellingUnit)
        .where(
            ProductSellingUnit.product_id == product_id,
            ProductSellingUnit.tenant_id == user.tenant_id,
        )
        .order_by(ProductSellingUnit.sort_order)
    )
    units = r.scalars().all()
    result = []
    for u in units:
        out = SellingUnitOut.model_validate(u)
        out.base_price = float(product.base_price)
        result.append(out)
    return result


@router.post("/unit-split/products/{product_id}/units", response_model=SellingUnitOut, status_code=201)
async def create_product_unit(
    product_id: int,
    body: SellingUnitIn,
    db: AsyncSession = Depends(get_db),
    user: User = Depends(get_admin_user),
):
    from app.core.models.product import Product
    prod_r = await db.execute(
        select(Product).where(Product.id == product_id, Product.tenant_id == user.tenant_id)
    )
    product = prod_r.scalar_one_or_none()
    if product is None:
        raise HTTPException(status_code=404, detail="商品不存在")

    if body.is_base_unit:
        existing_base_r = await db.execute(
            select(ProductSellingUnit).where(
                ProductSellingUnit.product_id == product_id,
                ProductSellingUnit.tenant_id == user.tenant_id,
                ProductSellingUnit.is_base_unit == 1,
            )
        )
        if existing_base_r.scalar_one_or_none():
            raise HTTPException(status_code=400, detail="每个商品只能有一个基础单位")

    unit = ProductSellingUnit(
        tenant_id=user.tenant_id,
        product_id=product_id,
        dict_id=body.dict_id,
        unit_name=body.unit_name,
        unit_name_en=body.unit_name_en,
        qty_per_base=body.qty_per_base,
        is_base_unit=1 if body.is_base_unit else 0,
        price_override=body.price_override,
        sort_order=body.sort_order,
    )
    db.add(unit)
    await db.commit()
    await db.refresh(unit)
    out = SellingUnitOut.model_validate(unit)
    out.base_price = float(product.base_price)
    return out


@router.put("/unit-split/units/{unit_id}", response_model=SellingUnitOut)
async def update_product_unit(
    unit_id: int,
    body: SellingUnitIn,
    db: AsyncSession = Depends(get_db),
    user: User = Depends(get_admin_user),
):
    r = await db.execute(
        select(ProductSellingUnit).where(
            ProductSellingUnit.id == unit_id,
            ProductSellingUnit.tenant_id == user.tenant_id,
        )
    )
    unit = r.scalar_one_or_none()
    if unit is None:
        raise HTTPException(status_code=404, detail="销售单位不存在")

    unit.dict_id = body.dict_id
    unit.unit_name = body.unit_name
    unit.unit_name_en = body.unit_name_en
    unit.qty_per_base = body.qty_per_base
    unit.is_base_unit = 1 if body.is_base_unit else 0
    unit.price_override = body.price_override
    unit.sort_order = body.sort_order
    await db.commit()
    await db.refresh(unit)

    from app.core.models.product import Product
    prod_r = await db.execute(
        select(Product).where(Product.id == unit.product_id, Product.tenant_id == user.tenant_id)
    )
    product = prod_r.scalar_one_or_none()
    out = SellingUnitOut.model_validate(unit)
    out.base_price = float(product.base_price) if product else 0.0
    return out


@router.delete("/unit-split/units/{unit_id}", status_code=204)
async def delete_product_unit(
    unit_id: int,
    db: AsyncSession = Depends(get_db),
    user: User = Depends(get_admin_user),
):
    r = await db.execute(
        select(ProductSellingUnit).where(
            ProductSellingUnit.id == unit_id,
            ProductSellingUnit.tenant_id == user.tenant_id,
        )
    )
    unit = r.scalar_one_or_none()
    if unit is None:
        raise HTTPException(status_code=404, detail="销售单位不存在")
    if unit.is_base_unit:
        raise HTTPException(status_code=400, detail="基础单位不可删除，请先删除其他单位")
    await db.delete(unit)
    await db.commit()
