"""
FluxTokens API Errors
"""

from typing import Optional


class FluxTokensError(Exception):
    """Base error class for FluxTokens API errors."""

    def __init__(
        self,
        message: str,
        status: Optional[int] = None,
        code: Optional[str] = None,
        error_type: Optional[str] = None,
        param: Optional[str] = None,
    ) -> None:
        super().__init__(message)
        self.message = message
        self.status = status
        self.code = code
        self.error_type = error_type
        self.param = param

    def __str__(self) -> str:
        return self.message

    def __repr__(self) -> str:
        return f"{self.__class__.__name__}(message={self.message!r}, status={self.status})"


class AuthenticationError(FluxTokensError):
    """Error raised when authentication fails (401)."""

    def __init__(self, message: str = "Invalid API key") -> None:
        super().__init__(
            message=message,
            status=401,
            code="invalid_api_key",
            error_type="authentication_error",
        )


class RateLimitError(FluxTokensError):
    """Error raised when rate limit is exceeded (429)."""

    def __init__(
        self,
        message: str = "Rate limit exceeded",
        retry_after: Optional[int] = None,
    ) -> None:
        super().__init__(
            message=message,
            status=429,
            code="rate_limit_exceeded",
            error_type="rate_limit_error",
        )
        self.retry_after = retry_after


class InsufficientBalanceError(FluxTokensError):
    """Error raised when balance is insufficient (402)."""

    def __init__(self, message: str = "Insufficient balance") -> None:
        super().__init__(
            message=message,
            status=402,
            code="insufficient_balance",
            error_type="payment_required",
        )


class BadRequestError(FluxTokensError):
    """Error raised when request is invalid (400)."""

    def __init__(
        self,
        message: str,
        code: Optional[str] = None,
        param: Optional[str] = None,
    ) -> None:
        super().__init__(
            message=message,
            status=400,
            code=code,
            error_type="invalid_request_error",
            param=param,
        )


class InternalServerError(FluxTokensError):
    """Error raised when server error occurs (500+)."""

    def __init__(self, message: str = "Internal server error") -> None:
        super().__init__(
            message=message,
            status=500,
            code="internal_error",
            error_type="server_error",
        )


class TimeoutError(FluxTokensError):
    """Error raised when request times out."""

    def __init__(self, message: str = "Request timed out") -> None:
        super().__init__(
            message=message,
            code="timeout",
            error_type="timeout_error",
        )


class ConnectionError(FluxTokensError):
    """Error raised when connection fails."""

    def __init__(self, message: str = "Connection failed") -> None:
        super().__init__(
            message=message,
            code="connection_error",
            error_type="connection_error",
        )
