"""Error types for the Cerebe SDK."""

from __future__ import annotations

from typing import Any


class CerebeError(Exception):
    """Base error for all Cerebe SDK errors."""

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

    def __repr__(self) -> str:
        parts = [f"message={self.message!r}"]
        if self.status_code:
            parts.append(f"status_code={self.status_code}")
        if self.code:
            parts.append(f"code={self.code!r}")
        if self.request_id:
            parts.append(f"request_id={self.request_id!r}")
        return f"{type(self).__name__}({', '.join(parts)})"


class AuthenticationError(CerebeError):
    """Raised when authentication fails (401)."""

    pass


class RateLimitError(CerebeError):
    """Raised when rate limited (429)."""

    def __init__(
        self,
        message: str,
        *,
        retry_after: float | None = None,
        **kwargs: object,
    ) -> None:
        super().__init__(message, status_code=429, **kwargs)  # type: ignore[arg-type]
        self.retry_after = retry_after


class NotFoundError(CerebeError):
    """Raised when a resource is not found (404)."""

    pass


class ValidationError(CerebeError):
    """Raised when request validation fails (400/422)."""

    pass


class ServerError(CerebeError):
    """Raised on server errors (5xx)."""

    pass


def raise_for_status(status_code: int, body: dict[str, Any]) -> None:
    """Raise an appropriate error based on HTTP status code."""
    if status_code < 400:
        return

    error = body.get("error", {})
    message = error.get("message", f"HTTP {status_code}")
    code = error.get("code")
    request_id = error.get("request_id")

    kwargs = {"status_code": status_code, "code": code, "request_id": request_id}

    if status_code == 401:
        raise AuthenticationError(message, **kwargs)
    elif status_code == 404:
        raise NotFoundError(message, **kwargs)
    elif status_code == 429:
        raise RateLimitError(message, retry_after=None, **kwargs)
    elif status_code in (400, 422):
        raise ValidationError(message, **kwargs)
    elif status_code >= 500:
        raise ServerError(message, **kwargs)
    else:
        raise CerebeError(message, **kwargs)
