"""
Custom exceptions for AltSportsData SDK
"""

from typing import Optional


class AltSportsDataError(Exception):
    """Base exception for all AltSportsData SDK errors"""

    def __init__(self, message: str, status_code: Optional[int] = None):
        super().__init__(message)
        self.message = message
        self.status_code = status_code

    def __str__(self) -> str:
        if self.status_code:
            return f"[HTTP {self.status_code}] {self.message}"
        return self.message


class AuthenticationError(AltSportsDataError):
    """Raised when authentication fails (invalid API key)"""

    def __init__(self, message: str = "Authentication failed. Check your API key."):
        super().__init__(message, 401)


class ValidationError(AltSportsDataError):
    """Raised when request validation fails"""

    def __init__(self, message: str = "Request validation failed."):
        super().__init__(message, 422)


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

    def __init__(self, message: str = "Rate limit exceeded.", retry_after: Optional[int] = None):
        super().__init__(message, 429)
        self.retry_after = retry_after

    def __str__(self) -> str:
        if self.retry_after:
            return f"{self.message} Retry after {self.retry_after} seconds."
        return self.message


class NotFoundError(AltSportsDataError):
    """Raised when requested resource is not found"""

    def __init__(self, message: str = "Resource not found."):
        super().__init__(message, 404)


class PermissionError(AltSportsDataError):
    """Raised when user doesn't have permission"""

    def __init__(self, message: str = "Insufficient permissions."):
        super().__init__(message, 403)


class ServerError(AltSportsDataError):
    """Raised when server encounters an internal error"""

    def __init__(self, message: str = "Internal server error."):
        super().__init__(message, 500)


class NetworkError(AltSportsDataError):
    """Raised when network connectivity issues occur"""

    def __init__(self, message: str = "Network error."):
        super().__init__(message)


class ConfigurationError(AltSportsDataError):
    """Raised when SDK is not properly configured"""

    def __init__(self, message: str = "SDK configuration error."):
        super().__init__(message)


class DataFormatError(AltSportsDataError):
    """Raised when response data format is invalid"""

    def __init__(self, message: str = "Invalid data format."):
        super().__init__(message)


def raise_for_status(status_code: int, message: Optional[str] = None) -> None:
    """Raise the appropriate exception for an HTTP error status code."""
    defaults = {
        400: "Bad request.",
        401: "Authentication failed. Check your API key.",
        403: "Insufficient permissions.",
        404: "Resource not found.",
        422: "Validation failed.",
        429: "Rate limit exceeded.",
        500: "Internal server error.",
    }
    msg = message or defaults.get(status_code, f"HTTP error {status_code}.")

    if status_code == 400:
        raise ValidationError(msg)
    elif status_code == 401:
        raise AuthenticationError(msg)
    elif status_code == 403:
        raise PermissionError(msg)
    elif status_code == 404:
        raise NotFoundError(msg)
    elif status_code == 422:
        raise ValidationError(msg)
    elif status_code == 429:
        raise RateLimitError(msg)
    elif status_code >= 500:
        raise ServerError(msg)
    else:
        raise AltSportsDataError(msg, status_code)
