"""Typed error classes matching Wallgent API error codes."""

from __future__ import annotations

from typing import Any, Dict, Optional


class WallgentError(Exception):
    """Base error for all Wallgent API errors."""

    def __init__(
        self,
        code: str,
        message: str,
        status_code: int,
        details: Optional[Dict[str, Any]] = None,
    ) -> None:
        super().__init__(message)
        self.code = code
        self.status_code = status_code
        self.details = details


class InsufficientFundsError(WallgentError):
    def __init__(self, message: str, details: Optional[Dict[str, Any]] = None) -> None:
        super().__init__("INSUFFICIENT_FUNDS", message, 402, details)


class PolicyDeniedError(WallgentError):
    def __init__(self, message: str, details: Optional[Dict[str, Any]] = None) -> None:
        super().__init__("POLICY_DENIED", message, 403, details)


class WalletNotFoundError(WallgentError):
    def __init__(self, message: str, details: Optional[Dict[str, Any]] = None) -> None:
        super().__init__("WALLET_NOT_FOUND", message, 404, details)


class InvalidAmountError(WallgentError):
    def __init__(self, message: str, details: Optional[Dict[str, Any]] = None) -> None:
        super().__init__("INVALID_AMOUNT", message, 400, details)


class EnvironmentMismatchError(WallgentError):
    def __init__(self, message: str, details: Optional[Dict[str, Any]] = None) -> None:
        super().__init__("ENVIRONMENT_MISMATCH", message, 403, details)


class RateLimitExceededError(WallgentError):
    def __init__(self, message: str, details: Optional[Dict[str, Any]] = None) -> None:
        super().__init__("RATE_LIMIT_EXCEEDED", message, 429, details)


class UnauthorizedError(WallgentError):
    def __init__(self, message: str, details: Optional[Dict[str, Any]] = None) -> None:
        super().__init__("UNAUTHORIZED", message, 401, details)


class ValidationError(WallgentError):
    def __init__(self, message: str, details: Optional[Dict[str, Any]] = None) -> None:
        super().__init__("VALIDATION_ERROR", message, 400, details)


_ERROR_MAP: Dict[str, type] = {
    "INSUFFICIENT_FUNDS": InsufficientFundsError,
    "POLICY_DENIED": PolicyDeniedError,
    "WALLET_NOT_FOUND": WalletNotFoundError,
    "INVALID_AMOUNT": InvalidAmountError,
    "ENVIRONMENT_MISMATCH": EnvironmentMismatchError,
    "RATE_LIMIT_EXCEEDED": RateLimitExceededError,
    "UNAUTHORIZED": UnauthorizedError,
    "VALIDATION_ERROR": ValidationError,
}


def create_error_from_response(status: int, body: Dict[str, Any]) -> WallgentError:
    """Create a typed error from an API error response."""
    error = body.get("error", {})
    code = error.get("code", "API_ERROR")
    message = error.get("message", f"API error: {status}")
    details = error.get("details")
    cls = _ERROR_MAP.get(code)
    if cls:
        return cls(message, details)
    return WallgentError(code, message, status, details)
