"""
Integration Exceptions

Exceptions for external service and integration errors.
"""

from typing import Any, Optional, Dict

from .base import NexaException


class IntegrationException(NexaException):
    """Base exception for integration errors."""

    message = "Integration error"
    code = "INTEGRATION_ERROR"
    http_status = 502


class ExternalServiceException(IntegrationException):
    """Raised when an external service call fails."""

    message = "External service error"
    code = "EXTERNAL_SERVICE_ERROR"

    def __init__(
        self,
        service_name: str,
        status_code: Optional[int] = None,
        response_body: Optional[str] = None,
        **kwargs,
    ):
        message = f"External service '{service_name}' returned an error"
        if status_code:
            message += f" (status: {status_code})"
        details = {"service_name": service_name}
        if status_code:
            details["status_code"] = status_code
        if response_body:
            details["response_body"] = response_body[:500]  # Truncate
        super().__init__(message=message, details=details, **kwargs)


class TimeoutException(IntegrationException):
    """Raised when an operation times out."""

    message = "Operation timed out"
    code = "TIMEOUT"
    http_status = 504

    def __init__(
        self,
        operation: str,
        timeout_seconds: Optional[float] = None,
        **kwargs,
    ):
        message = f"Operation '{operation}' timed out"
        if timeout_seconds:
            message += f" after {timeout_seconds}s"
        details = {"operation": operation}
        if timeout_seconds:
            details["timeout_seconds"] = timeout_seconds
        super().__init__(message=message, details=details, **kwargs)


class ConnectionException(IntegrationException):
    """Raised when connection to a service fails."""

    message = "Connection failed"
    code = "CONNECTION_ERROR"

    def __init__(
        self,
        host: str,
        port: Optional[int] = None,
        reason: Optional[str] = None,
        **kwargs,
    ):
        message = f"Failed to connect to '{host}'"
        if port:
            message += f":{port}"
        if reason:
            message += f": {reason}"
        details = {"host": host}
        if port:
            details["port"] = port
        if reason:
            details["reason"] = reason
        super().__init__(message=message, details=details, **kwargs)


class WebhookException(IntegrationException):
    """Raised when webhook delivery fails."""

    message = "Webhook delivery failed"
    code = "WEBHOOK_ERROR"

    def __init__(
        self,
        webhook_url: str,
        attempt: int = 1,
        max_attempts: int = 3,
        **kwargs,
    ):
        message = f"Webhook delivery to '{webhook_url}' failed (attempt {attempt}/{max_attempts})"
        details = {
            "webhook_url": webhook_url,
            "attempt": attempt,
            "max_attempts": max_attempts,
        }
        super().__init__(message=message, details=details, **kwargs)
