"""SDK exception hierarchy."""

from __future__ import annotations

from typing import Any

import httpx


class ValidatorError(Exception):
    """Base exception for SDK errors."""


class APIError(ValidatorError):
    """HTTP error returned by the validator API."""

    def __init__(
        self,
        status_code: int,
        detail: str,
        response: httpx.Response | None = None,
    ) -> None:
        self.status_code = status_code
        self.detail = detail
        self.response = response
        super().__init__(f"HTTP {status_code}: {detail}")


class BadRequestError(APIError):
    """400 from API."""


class AuthenticationError(APIError):
    """401 from API."""


class PaymentRequiredError(APIError):
    """402 from API."""


class RateLimitError(APIError):
    """429 from API."""

    def __init__(
        self,
        status_code: int,
        detail: str,
        response: httpx.Response | None = None,
        retry_after: int | None = None,
    ) -> None:
        self.retry_after = retry_after
        super().__init__(status_code=status_code, detail=detail, response=response)


class ServiceUnavailableError(APIError):
    """503 from API."""


class TimeoutError(ValidatorError):
    """Timeout reaching API or 504 returned by API."""


class ConnectionError(ValidatorError):
    """Network/connectivity failure while calling API."""


class CryptoNotAvailableError(ValidatorError):
    """Raised when crypto helper dependencies are unavailable."""


def parse_error_detail(payload: Any, fallback: str) -> str:
    """Extract a readable error string from API payload."""
    if isinstance(payload, dict):
        detail = payload.get("detail")
        error = payload.get("error")
        if isinstance(detail, str) and isinstance(error, str):
            if detail == error:
                return detail
            return f"{error}: {detail}"
        if isinstance(detail, str):
            return detail
        if isinstance(error, str):
            return error
    return fallback
