class LatchError(Exception):
    """Base exception for Latch SDK"""

    def __init__(self, message: str, code: str | None = None):
        self.message = message
        self.code = code
        super().__init__(message)


class AuthenticationError(LatchError):
    """Raised when API key is invalid or missing"""

    def __init__(self, message: str = "Invalid or missing API key"):
        super().__init__(message, code="AUTHENTICATION_ERROR")


class BudgetExceededError(LatchError):
    """Raised when budget limit is exceeded"""

    def __init__(
        self,
        message: str = "Budget limit exceeded",
        *,
        current_spend: float | None = None,
        budget_limit: float | None = None,
    ):
        self.current_spend = current_spend
        self.budget_limit = budget_limit
        super().__init__(message, code="BUDGET_EXCEEDED")


class RateLimitError(LatchError):
    """Raised when rate limit is exceeded"""

    def __init__(
        self,
        message: str = "Rate limit exceeded",
        *,
        retry_after: int | None = None,
    ):
        self.retry_after = retry_after
        super().__init__(message, code="RATE_LIMIT_EXCEEDED")


class RequestBlockedError(LatchError):
    """Raised when request is blocked by policy"""

    def __init__(self, message: str = "Request blocked by policy"):
        super().__init__(message, code="REQUEST_BLOCKED")
