"""Exceptions pour le SDK STRIGIVAL."""


class StrigivalError(Exception):
    """Exception de base pour le SDK STRIGIVAL."""
    
    def __init__(self, message: str, code: str = None, details: dict = None):
        super().__init__(message)
        self.message = message
        self.code = code
        self.details = details or {}
    
    def __str__(self) -> str:
        if self.code:
            return f"[{self.code}] {self.message}"
        return self.message


class AuthenticationError(StrigivalError):
    """Erreur d'authentification."""
    
    def __init__(self, message: str = "Authentication failed", details: dict = None):
        super().__init__(message, code="AUTH_ERROR", details=details)


class QuoteError(StrigivalError):
    """Erreur lors de la récupération d'un quote."""
    
    def __init__(self, message: str = "Failed to get quote", details: dict = None):
        super().__init__(message, code="QUOTE_ERROR", details=details)


class TradeError(StrigivalError):
    """Erreur lors de l'exécution d'un trade."""
    
    def __init__(self, message: str = "Trade execution failed", details: dict = None):
        super().__init__(message, code="TRADE_ERROR", details=details)


class RateLimitError(StrigivalError):
    """Erreur de rate limiting."""
    
    def __init__(
        self,
        message: str = "Rate limit exceeded",
        retry_after: int = None,
        details: dict = None
    ):
        super().__init__(message, code="RATE_LIMIT", details=details)
        self.retry_after = retry_after
    
    def __str__(self) -> str:
        base = super().__str__()
        if self.retry_after:
            return f"{base} (retry after {self.retry_after}s)"
        return base


class ValidationError(StrigivalError):
    """Erreur de validation des paramètres."""
    
    def __init__(self, message: str = "Validation failed", field: str = None, details: dict = None):
        super().__init__(message, code="VALIDATION_ERROR", details=details)
        self.field = field


class NetworkError(StrigivalError):
    """Erreur réseau."""
    
    def __init__(self, message: str = "Network error", details: dict = None):
        super().__init__(message, code="NETWORK_ERROR", details=details)


class ContractError(StrigivalError):
    """Erreur lors de l'interaction avec un smart contract."""
    
    def __init__(self, message: str = "Contract error", details: dict = None):
        super().__init__(message, code="CONTRACT_ERROR", details=details)


class InsufficientFundsError(StrigivalError):
    """Fonds insuffisants pour l'opération."""
    
    def __init__(
        self,
        message: str = "Insufficient funds",
        required: int = None,
        available: int = None,
        details: dict = None
    ):
        super().__init__(message, code="INSUFFICIENT_FUNDS", details=details)
        self.required = required
        self.available = available


class SlippageError(TradeError):
    """Slippage trop élevé."""
    
    def __init__(
        self,
        message: str = "Slippage exceeded",
        expected: int = None,
        actual: int = None,
        details: dict = None
    ):
        super().__init__(message, details=details)
        self.code = "SLIPPAGE_ERROR"
        self.expected = expected
        self.actual = actual


class CircuitBreakerError(TradeError):
    """Circuit breaker activé."""
    
    def __init__(
        self,
        message: str = "Circuit breaker triggered",
        level: int = None,
        details: dict = None
    ):
        super().__init__(message, details=details)
        self.code = "CIRCUIT_BREAKER"
        self.level = level
