from fastapi import FastAPI, Request
from fastapi.responses import JSONResponse
from sqlalchemy.exc import IntegrityError

from flyway.domain.errors import BusinessError, PermissionDenied

# 唯一索引（迁移 0001）→ 表单字段；并发下“先查后写”漏过时由数据库兜底
UNIQUE_FIELDS = {
    "ux_transfer_code": "code",
    "ux_packing_slip_reference": "reference",
    "ux_parcel_barcode": "barcode",
    "ux_batch_number": "batch_number",
    "ux_app_user_username": "username",
}


def install(app: FastAPI) -> None:
    @app.exception_handler(BusinessError)
    async def business_error(_: Request, exc: BusinessError):
        status = 403 if isinstance(exc, PermissionDenied) else 400
        return JSONResponse(status_code=status, content={"message": exc.message, "field": exc.field})

    @app.exception_handler(IntegrityError)
    async def integrity_error(_: Request, exc: IntegrityError):
        constraint = getattr(getattr(exc.orig, "diag", None), "constraint_name", None)
        if getattr(exc.orig, "sqlstate", None) != "23505" or constraint not in UNIQUE_FIELDS:
            raise exc
        return JSONResponse(status_code=400,
                            content={"message": "This value already exists.", "field": UNIQUE_FIELDS[constraint]})
