"""SnelStart integration errors — safe to expose user-facing messages."""

from __future__ import annotations


class SnelStartError(Exception):
    """Base class for SnelStart integration failures."""

    code: str = "UnknownIntegrationError"
    user_message: str = "SnelStart integration is unavailable."

    def __init__(self, message: str | None = None, *, user_message: str | None = None) -> None:
        super().__init__(message or self.user_message)
        if user_message:
            self.user_message = user_message


class SnelStartNotConnected(SnelStartError):
    code = "NotConnected"
    user_message = "SnelStart is not connected for this client."


class SnelStartIntegrationDisabled(SnelStartError):
    code = "IntegrationDisabled"
    user_message = "SnelStart integration is not enabled yet."


class SnelStartAuthenticationFailed(SnelStartError):
    code = "AuthenticationFailed"
    user_message = "SnelStart authentication failed. Please reconnect the integration."


class SnelStartAuthorizationFailed(SnelStartError):
    code = "AuthorizationFailed"
    user_message = "SnelStart access was denied for this administration."


class SnelStartRateLimited(SnelStartError):
    code = "RateLimited"
    user_message = "SnelStart is temporarily rate limiting requests. Please try again later."


class SnelStartValidationError(SnelStartError):
    code = "ValidationError"
    user_message = "SnelStart rejected the submitted bookkeeping data."


class SnelStartExternalAPIError(SnelStartError):
    code = "ExternalAPIError"
    user_message = "SnelStart returned an unexpected error."


class SnelStartTimeout(SnelStartError):
    code = "Timeout"
    user_message = "SnelStart did not respond in time. Please try again."


def http_status_for(error: SnelStartError) -> int:
    if isinstance(error, (SnelStartNotConnected, SnelStartIntegrationDisabled)):
        return 503
    if isinstance(error, SnelStartAuthenticationFailed):
        return 401
    if isinstance(error, SnelStartAuthorizationFailed):
        return 403
    if isinstance(error, SnelStartRateLimited):
        return 429
    if isinstance(error, SnelStartValidationError):
        return 422
    if isinstance(error, SnelStartTimeout):
        return 504
    return 502
