import httpx
from litestar import MediaType, Request, Response
from litestar.exceptions import HTTPException
from litestar.response import Redirect
from litestar.status_codes import HTTP_500_INTERNAL_SERVER_ERROR
from loguru import logger


def http_exception_handler(_: Request, exc: HTTPException) -> Response:
    status_code = getattr(exc, "status_code", HTTP_500_INTERNAL_SERVER_ERROR)
    detail = getattr(exc, "detail", "")

    if isinstance(exc, HTTPException) and (exc.status_code in [401, 403]):
        logger.warning("User could not authenticate. Redirecting to /login page")
        return Redirect("/login")

    return Response(
        media_type=MediaType.TEXT,
        content=detail,
        status_code=status_code,
    )


def httpx_status_error_handler(_: Request, exc: httpx.HTTPStatusError):
    logger.error(f"HTTPX error occurred: {exc}")
    return Response(
        media_type=MediaType.TEXT,
        content=f"HTTPX error occurred: {exc}",
        status_code=exc.response.status_code,
    )


async def after_exception_handler(exc: Exception, scope: "Scope") -> None:  # type: ignore[name-defined]  # noqa: F821
    """Hook function that will be invoked after each exception."""
    state = scope["app"].state
    if not hasattr(state, "error_count"):
        state.error_count = 1
    else:
        state.error_count += 1
    logger.error(
        f"an exception of type {type(exc).__name__} has occurred for requested path {scope['path']} and the application error count is {state.error_count}.",
    )
    import traceback

    traceback.print_exc()
