"""Duffel API exceptions."""

from .models import Error, ErrorResponse


class DuffelError(Exception):
    """Base exception for all Duffel API errors."""

    def __init__(self, message: str, status_code: int | None = None, errors: list[Error] | None = None):
        self.status_code = status_code
        self.errors = errors or []
        super().__init__(message)


class AuthenticationError(DuffelError):
    """Raised for 401 authentication failures."""


class PermissionError(DuffelError):
    """Raised for 403 forbidden responses."""


class NotFoundError(DuffelError):
    """Raised for 404 responses."""


class ValidationError(DuffelError):
    """Raised for 422 validation errors."""


class RateLimitError(DuffelError):
    """Raised for 429 rate limit errors."""

    def __init__(self, message: str, reset_at: str | None = None, **kwargs):
        self.reset_at = reset_at
        super().__init__(message, **kwargs)


class ApiError(DuffelError):
    """Raised for 5xx server errors."""


_STATUS_TO_EXCEPTION: dict[int, type[DuffelError]] = {
    401: AuthenticationError,
    403: PermissionError,
    404: NotFoundError,
    422: ValidationError,
    429: RateLimitError,
}


def raise_for_response(status_code: int, body: dict | None, headers: dict | None = None) -> None:
    """Parse an error response and raise the appropriate exception."""
    errors: list[Error] = []
    message = f"Duffel API error (HTTP {status_code})"

    if body and "errors" in body:
        error_resp = ErrorResponse.model_validate(body)
        errors = error_resp.errors or []
        if errors:
            message = f"{errors[0].title}: {errors[0].message}"

    exc_class = _STATUS_TO_EXCEPTION.get(status_code, ApiError if status_code >= 500 else DuffelError)

    kwargs: dict = {"status_code": status_code, "errors": errors}
    if exc_class is RateLimitError and headers:
        kwargs["reset_at"] = headers.get("ratelimit-reset")

    raise exc_class(message, **kwargs)
