from typing import Any, Dict, Optional

class SearchCoordinatorException(Exception):
    """Base exception for search coordinator"""
    def __init__(
        self,
        message: str,
        error_code: str = "SEARCH_COORDINATOR_ERROR",
        details: Optional[Dict[str, Any]] = None
    ):
        self.message = message
        self.error_code = error_code
        self.details = details or {}
        super().__init__(self.message)

class SearchRequestNotFound(SearchCoordinatorException):
    """Search request not found exception"""
    def __init__(self, request_id: str):
        super().__init__(
            message=f"Search request not found: {request_id}",
            error_code="SEARCH_REQUEST_NOT_FOUND",
            details={"request_id": request_id}
        )

class InvalidSearchPlatform(SearchCoordinatorException):
    """Invalid search platform exception"""
    def __init__(self, platform: str):
        super().__init__(
            message=f"Invalid search platform: {platform}",
            error_code="INVALID_SEARCH_PLATFORM",
            details={"platform": platform}
        )

class KafkaConnectionError(SearchCoordinatorException):
    """Kafka connection error"""
    def __init__(self, details: str):
        super().__init__(
            message=f"Kafka connection error: {details}",
            error_code="KAFKA_CONNECTION_ERROR",
            details={"kafka_error": details}
        )

class DatabaseConnectionError(SearchCoordinatorException):
    """Database connection error"""
    def __init__(self, details: str):
        super().__init__(
            message=f"Database connection error: {details}",
            error_code="DATABASE_CONNECTION_ERROR",
            details={"database_error": details}
        )

class SearchTaskDistributionError(SearchCoordinatorException):
    """Search task distribution error"""
    def __init__(self, task_id: str, platform: str, details: str):
        super().__init__(
            message=f"Failed to distribute search task {task_id} to {platform}: {details}",
            error_code="SEARCH_TASK_DISTRIBUTION_ERROR",
            details={
                "task_id": task_id,
                "platform": platform,
                "error_details": details
            }
        )
