"""Custom exceptions for the Danube SDK."""

from typing import Optional


class DanubeError(Exception):
    """Base exception for all Danube SDK errors."""

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

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


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

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


class AuthorizationError(DanubeError):
    """Raised when user lacks permission for a resource."""

    def __init__(self, message: str = "Permission denied"):
        super().__init__(message, status_code=403)


class NotFoundError(DanubeError):
    """Raised when a requested resource doesn't exist."""

    def __init__(self, resource: str = "Resource", identifier: str = "", message: str = ""):
        if message:
            self.resource = resource
            self.identifier = identifier
            super().__init__(message, status_code=404)
        else:
            msg = f"{resource} not found"
            if identifier:
                msg = f"{resource} '{identifier}' not found"
            self.resource = resource
            self.identifier = identifier
            super().__init__(msg, status_code=404)


class ValidationError(DanubeError):
    """Raised when request parameters are invalid."""

    def __init__(self, message: str = "Invalid request parameters"):
        super().__init__(message, status_code=400)


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

    def __init__(self, retry_after: Optional[int] = None):
        message = "Rate limit exceeded"
        if retry_after:
            message += f". Retry after {retry_after} seconds"
        self.retry_after = retry_after
        super().__init__(message, status_code=429)


class ExecutionError(DanubeError):
    """Raised when tool execution fails."""

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


class ConfigurationRequiredError(DanubeError):
    """Raised when a service requires credential configuration."""

    def __init__(
        self,
        service_id: str,
        service_name: str = "",
        configuration_url: Optional[str] = None,
    ):
        self.service_id = service_id
        self.service_name = service_name
        self.configuration_url = (
            configuration_url
            or f"https://app.danube.ai/dashboard/services/{service_id}"
        )

        message = f"Service '{service_name or service_id}' requires credential configuration"
        super().__init__(message, status_code=403)


class DanubeConnectionError(DanubeError):
    """Raised when unable to connect to the API."""

    def __init__(self, message: str = "Failed to connect to Danube API"):
        super().__init__(message, status_code=503)


class DanubeTimeoutError(DanubeError):
    """Raised when a request times out."""

    def __init__(self, message: str = "Request timed out"):
        super().__init__(message, status_code=504)
