"""
Kafka error handling module.

This module defines custom exceptions and error handlers for Kafka operations.
"""


class KafkaError(Exception):
    """Base exception for Kafka-related errors."""

    pass


class ConfigurationError(KafkaError):
    """Exception raised for configuration-related errors."""

    def __init__(self, message: str, config_key: str = None):
        self.config_key = config_key
        super().__init__(message)


class ConnectionError(KafkaError):
    """Exception raised for connection-related errors."""

    def __init__(self, message: str, bootstrap_servers: str = None):
        self.bootstrap_servers = bootstrap_servers
        super().__init__(message)


class ProducerError(KafkaError):
    """Exception raised for producer-related errors."""

    def __init__(self, message: str, producer_id: str = None):
        self.producer_id = producer_id
        super().__init__(message)


class ConsumerError(KafkaError):
    """Exception raised for consumer-related errors."""

    def __init__(self, message: str, consumer_id: str = None):
        self.consumer_id = consumer_id
        super().__init__(message)


class TopicError(KafkaError):
    """Exception raised for topic-related errors."""

    def __init__(self, message: str, topic_name: str = None):
        self.topic_name = topic_name
        super().__init__(message)


class ConsumerGroupError(KafkaError):
    """Exception raised for consumer group-related errors."""

    def __init__(self, message: str, group_id: str = None):
        self.group_id = group_id
        super().__init__(message)


class MessageError(KafkaError):
    """Exception raised for message-related errors."""

    def __init__(self, message: str, topic: str = None, partition: int = None):
        self.topic = topic
        self.partition = partition
        super().__init__(message)


class TimeoutError(KafkaError):
    """Exception raised for timeout errors."""

    def __init__(self, message: str, operation: str = None):
        self.operation = operation
        super().__init__(message)


class SerializationError(KafkaError):
    """Exception raised for serialization/deserialization errors."""

    def __init__(self, message: str, data_type: str = None):
        self.data_type = data_type
        super().__init__(message)


class ErrorHandler:
    """Error handler for Kafka operations."""

    @staticmethod
    def handle_error(error: Exception) -> str:
        """
        Handle Kafka errors and return user-friendly error messages.

        Args:
            error: Exception object

        Returns:
            User-friendly error message
        """
        if isinstance(error, ConfigurationError):
            return f"Configuration error: {str(error)}"

        elif isinstance(error, ConnectionError):
            return f"Connection failed: {str(error)}"

        elif isinstance(error, ProducerError):
            return f"Producer error: {str(error)}"

        elif isinstance(error, ConsumerError):
            return f"Consumer error: {str(error)}"

        elif isinstance(error, TopicError):
            return f"Topic error: {str(error)}"

        elif isinstance(error, ConsumerGroupError):
            return f"Consumer group error: {str(error)}"

        elif isinstance(error, MessageError):
            return f"Message error: {str(error)}"

        elif isinstance(error, TimeoutError):
            return f"Timeout error: {str(error)}"

        elif isinstance(error, SerializationError):
            return f"Serialization error: {str(error)}"

        else:
            return f"Unexpected error: {str(error)}"

    @staticmethod
    def get_error_details(error: Exception) -> dict:
        """
        Get detailed error information.

        Args:
            error: Exception object

        Returns:
            Dictionary with error details
        """
        details = {
            "type": type(error).__name__,
            "message": str(error),
        }

        # Add type-specific details
        if isinstance(error, ConfigurationError) and error.config_key:
            details["config_key"] = error.config_key

        elif isinstance(error, ConnectionError) and error.bootstrap_servers:
            details["bootstrap_servers"] = error.bootstrap_servers

        elif isinstance(error, ProducerError) and error.producer_id:
            details["producer_id"] = error.producer_id

        elif isinstance(error, ConsumerError) and error.consumer_id:
            details["consumer_id"] = error.consumer_id

        elif isinstance(error, TopicError) and error.topic_name:
            details["topic_name"] = error.topic_name

        elif isinstance(error, ConsumerGroupError) and error.group_id:
            details["group_id"] = error.group_id

        elif isinstance(error, MessageError):
            if error.topic:
                details["topic"] = error.topic
            if error.partition:
                details["partition"] = error.partition

        elif isinstance(error, TimeoutError) and error.operation:
            details["operation"] = error.operation

        elif isinstance(error, SerializationError) and error.data_type:
            details["data_type"] = error.data_type

        return details


def create_error_response(error: Exception) -> dict:
    """
    Create a standardized error response dictionary.

    Args:
        error: Exception object

    Returns:
        Dictionary with error information
    """
    return {
        "success": False,
        "error": ErrorHandler.handle_error(error),
        "details": ErrorHandler.get_error_details(error),
    }
