# backend/app/plugins/tax/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, require_permission
from app.core.models.user import User
from app.plugins.pos_sync.revision import bump_revision
from app.plugins.tax.models import TaxClass, TaxRate, TaxSettings
from app.plugins.tax.schemas import (
    TaxClassCreate, TaxClassUpdate, TaxClassOut,
    TaxRateCreate, TaxRateUpdate, TaxRateOut,
    TaxSettingsUpdate, TaxSettingsOut,
)

router = APIRouter(prefix="/tax", tags=["Tax"])


# ── Settings ─────────────────────────────────────────────────

@router.get("/settings", response_model=TaxSettingsOut, summary="获取税务设置")
async def get_tax_settings(
    db: AsyncSession = Depends(get_db),
    user: User = Depends(require_permission("settings.basic.view")),
):
    r = await db.execute(
        select(TaxSettings).where(TaxSettings.tenant_id == user.tenant_id)
    )
    row = r.scalar_one_or_none()
    if not row:
        row = TaxSettings(tenant_id=user.tenant_id)
        db.add(row)
        await db.commit()
        await db.refresh(row)
    return row


@router.put("/settings", response_model=TaxSettingsOut, summary="更新税务设置")
async def update_tax_settings(
    body: TaxSettingsUpdate,
    db: AsyncSession = Depends(get_db),
    user: User = Depends(require_permission("settings.basic.update")),
):
    r = await db.execute(
        select(TaxSettings).where(TaxSettings.tenant_id == user.tenant_id)
    )
    row = r.scalar_one_or_none()
    if not row:
        row = TaxSettings(tenant_id=user.tenant_id)
        db.add(row)

    for k, v in body.model_dump(exclude_unset=True).items():
        setattr(row, k, v)
    await bump_revision(db, user.tenant_id)
    await db.commit()
    await db.refresh(row)
    return row


# ── Tax Classes ──────────────────────────────────────────────

@router.get("/classes", response_model=list[TaxClassOut], summary="税种列表")
async def list_tax_classes(
    db: AsyncSession = Depends(get_db),
    user: User = Depends(require_permission("settings.basic.view")),
):
    r = await db.execute(
        select(TaxClass)
        .where(TaxClass.tenant_id == user.tenant_id)
        .order_by(TaxClass.sort_order, TaxClass.id)
    )
    return r.scalars().all()


@router.post("/classes", response_model=TaxClassOut, status_code=201, summary="创建税种")
async def create_tax_class(
    body: TaxClassCreate,
    db: AsyncSession = Depends(get_db),
    user: User = Depends(require_permission("settings.basic.update")),
):
    if body.is_default:
        existing = (await db.execute(
            select(TaxClass).where(TaxClass.tenant_id == user.tenant_id, TaxClass.is_default == 1)
        )).scalars().all()
        for tc in existing:
            tc.is_default = 0

    obj = TaxClass(tenant_id=user.tenant_id, **body.model_dump())
    db.add(obj)
    await bump_revision(db, user.tenant_id)
    await db.commit()
    await db.refresh(obj)
    return obj


@router.put("/classes/{class_id}", response_model=TaxClassOut, summary="更新税种")
async def update_tax_class(
    class_id: int,
    body: TaxClassUpdate,
    db: AsyncSession = Depends(get_db),
    user: User = Depends(require_permission("settings.basic.update")),
):
    r = await db.execute(
        select(TaxClass).where(TaxClass.id == class_id, TaxClass.tenant_id == user.tenant_id)
    )
    obj = r.scalar_one_or_none()
    if not obj:
        raise HTTPException(404, "税种不存在")

    data = body.model_dump(exclude_unset=True)
    if data.get("is_default"):
        existing = (await db.execute(
            select(TaxClass).where(TaxClass.tenant_id == user.tenant_id, TaxClass.is_default == 1)
        )).scalars().all()
        for tc in existing:
            tc.is_default = 0

    for k, v in data.items():
        setattr(obj, k, v)
    await bump_revision(db, user.tenant_id)
    await db.commit()
    await db.refresh(obj)
    return obj


@router.delete("/classes/{class_id}", status_code=204, summary="删除税种")
async def delete_tax_class(
    class_id: int,
    db: AsyncSession = Depends(get_db),
    user: User = Depends(require_permission("settings.basic.update")),
):
    r = await db.execute(
        select(TaxClass).where(TaxClass.id == class_id, TaxClass.tenant_id == user.tenant_id)
    )
    obj = r.scalar_one_or_none()
    if not obj:
        raise HTTPException(404, "税种不存在")

    from app.core.models.product import Product
    count = (await db.execute(
        select(Product.id).where(Product.tax_class_id == class_id).limit(1)
    )).scalar_one_or_none()
    if count is not None:
        raise HTTPException(400, "该税种下仍有商品关联，无法删除")

    await db.delete(obj)
    await bump_revision(db, user.tenant_id)
    await db.commit()


# ── Tax Rates ────────────────────────────────────────────────

@router.get("/classes/{class_id}/rates", response_model=list[TaxRateOut], summary="税率列表")
async def list_tax_rates(
    class_id: int,
    db: AsyncSession = Depends(get_db),
    user: User = Depends(require_permission("settings.basic.view")),
):
    r = await db.execute(
        select(TaxRate)
        .where(TaxRate.tax_class_id == class_id, TaxRate.tenant_id == user.tenant_id)
        .order_by(TaxRate.priority.desc(), TaxRate.country)
    )
    return r.scalars().all()


@router.post("/classes/{class_id}/rates", response_model=TaxRateOut, status_code=201, summary="添加税率")
async def create_tax_rate(
    class_id: int,
    body: TaxRateCreate,
    db: AsyncSession = Depends(get_db),
    user: User = Depends(require_permission("settings.basic.update")),
):
    tc = (await db.execute(
        select(TaxClass).where(TaxClass.id == class_id, TaxClass.tenant_id == user.tenant_id)
    )).scalar_one_or_none()
    if not tc:
        raise HTTPException(404, "税种不存在")

    data = body.model_dump()
    if not data.get("province"):
        data["province"] = None
    obj = TaxRate(tenant_id=user.tenant_id, tax_class_id=class_id, **data)
    db.add(obj)
    await bump_revision(db, user.tenant_id)
    await db.commit()
    await db.refresh(obj)
    return obj


@router.put("/rates/{rate_id}", response_model=TaxRateOut, summary="更新税率")
async def update_tax_rate(
    rate_id: int,
    body: TaxRateUpdate,
    db: AsyncSession = Depends(get_db),
    user: User = Depends(require_permission("settings.basic.update")),
):
    r = await db.execute(
        select(TaxRate).where(TaxRate.id == rate_id, TaxRate.tenant_id == user.tenant_id)
    )
    obj = r.scalar_one_or_none()
    if not obj:
        raise HTTPException(404, "税率不存在")

    for k, v in body.model_dump(exclude_unset=True).items():
        setattr(obj, k, v)
    await bump_revision(db, user.tenant_id)
    await db.commit()
    await db.refresh(obj)
    return obj


@router.delete("/rates/{rate_id}", status_code=204, summary="删除税率")
async def delete_tax_rate(
    rate_id: int,
    db: AsyncSession = Depends(get_db),
    user: User = Depends(require_permission("settings.basic.update")),
):
    r = await db.execute(
        select(TaxRate).where(TaxRate.id == rate_id, TaxRate.tenant_id == user.tenant_id)
    )
    obj = r.scalar_one_or_none()
    if not obj:
        raise HTTPException(404, "税率不存在")
    await db.delete(obj)
    await bump_revision(db, user.tenant_id)
    await db.commit()
