"""Exception hierarchy for the GoodMem SDK."""

from __future__ import annotations

from typing import TYPE_CHECKING

if TYPE_CHECKING:
    import httpx


class GoodMemError(Exception):
    """Base exception for all GoodMem SDK errors."""


class APIError(GoodMemError):
    """HTTP error from the GoodMem API."""

    def __init__(
        self,
        message: str,
        *,
        status_code: int,
        body: str | None = None,
    ) -> None:
        super().__init__(message)
        self.status_code = status_code
        self.body = body


class BadRequestError(APIError):
    """400 Bad Request."""


class AuthenticationError(APIError):
    """401 Unauthorized."""


class PermissionDeniedError(APIError):
    """403 Forbidden."""


class NotFoundError(APIError):
    """404 Not Found."""


class ConflictError(APIError):
    """409 Conflict (e.g., duplicate resource)."""


class UnprocessableEntityError(APIError):
    """422 Unprocessable Entity."""


class RateLimitError(APIError):
    """429 Too Many Requests."""


class InternalServerError(APIError):
    """5xx Server Error."""


_STATUS_TO_EXCEPTION: dict[int, type[APIError]] = {
    400: BadRequestError,
    401: AuthenticationError,
    403: PermissionDeniedError,
    404: NotFoundError,
    409: ConflictError,
    422: UnprocessableEntityError,
    429: RateLimitError,
}


def raise_for_status(response: httpx.Response) -> None:
    """Raise a typed exception based on HTTP status code."""
    status = response.status_code
    if status < 400:
        return

    try:
        body = response.text
    except Exception:
        body = None

    message = f"HTTP {status}"
    if body:
        message = f"HTTP {status}: {body[:500]}"

    exc_cls = _STATUS_TO_EXCEPTION.get(status)
    if exc_cls:
        raise exc_cls(message, status_code=status, body=body)
    if status >= 500:
        raise InternalServerError(message, status_code=status, body=body)
    raise APIError(message, status_code=status, body=body)
