"""Centralized API exception handlers."""

from __future__ import annotations

import logging

from fastapi import FastAPI
from fastapi import Request
from fastapi.responses import JSONResponse

from transcription.errors import AppError
from transcription.errors import ErrorCategory
from transcription.errors import build_error_envelope

logger = logging.getLogger(__name__)


_STATUS_BY_CATEGORY: dict[ErrorCategory, int] = {
    ErrorCategory.VALIDATION: 400,
    ErrorCategory.USER_INPUT: 400,
    ErrorCategory.NOT_FOUND: 404,
    ErrorCategory.CONFLICT: 409,
    ErrorCategory.EXTERNAL_PROVIDER: 503,
    ErrorCategory.INFRA_TRANSIENT: 503,
    ErrorCategory.INFRA_PERSISTENT: 500,
    ErrorCategory.INTERNAL_UNEXPECTED: 500,
}


def _status_for(error: AppError) -> int:
    return _STATUS_BY_CATEGORY.get(error.category, 500)


def register_error_handlers(app: FastAPI) -> None:
    """Register API exception handlers on the app."""

    @app.exception_handler(AppError)
    async def app_error_handler(_request: Request, exc: AppError) -> JSONResponse:
        envelope = build_error_envelope(exc)
        return JSONResponse(status_code=_status_for(exc), content=envelope.__dict__)

    @app.exception_handler(Exception)
    async def fallback_error_handler(_request: Request, exc: Exception) -> JSONResponse:
        normalized = AppError(
            "Unexpected error while handling request",
            category=ErrorCategory.INTERNAL_UNEXPECTED,
            suggestion="Retry once. If it persists, report the error reference id.",
        )
        logger.exception(
            "Unhandled API exception operation=api.request error_id=%s category=%s exception_type=%s",
            normalized.error_id,
            normalized.category.value,
            type(exc).__name__,
        )
        envelope = build_error_envelope(normalized)
        return JSONResponse(status_code=_status_for(normalized), content=envelope.__dict__)
