"""
Base MCP Adapter

Abstract base class for MCP client adapters that integrate LLM providers
with the HoneyDB MCP server.
"""

from abc import ABC, abstractmethod
from typing import Any, Callable

from honeydb_ai.domain.models import LLMResponse


class MCPAdapter(ABC):
    """
    Abstract base class for MCP client adapters.

    Each adapter implements MCP integration for a specific LLM provider,
    allowing the LLM to invoke HoneyDB tools via the MCP server.
    """

    def __init__(
        self,
        api_key: str,
        mcp_server_url: str,
        honeydb_api_id: str,
        honeydb_api_key: str,
        event_callback: Callable[[str, dict[str, Any]], None] | None = None,
    ):
        """
        Initialize MCP adapter.

        Args:
            api_key: LLM provider API key
            mcp_server_url: HoneyDB MCP server URL (SSE endpoint)
            honeydb_api_id: HoneyDB API ID for authentication
            honeydb_api_key: HoneyDB API key for authentication
            event_callback: Optional callback for MCP tool invocation events
        """
        self.api_key = api_key
        self.mcp_server_url = mcp_server_url
        self.honeydb_api_id = honeydb_api_id
        self.honeydb_api_key = honeydb_api_key
        self.event_callback = event_callback

    @abstractmethod
    async def send_message(
        self,
        messages: list[dict[str, Any]],
        model: str,
        temperature: float = 0.7,
        max_tokens: int | None = None,
    ) -> LLMResponse:
        """
        Send a message to the LLM with MCP server integration.

        The LLM can autonomously invoke HoneyDB tools via the MCP server
        during response generation.

        Args:
            messages: Conversation history in provider-specific format
            model: Model identifier (e.g., "gpt-4", "claude-sonnet-4")
            temperature: Sampling temperature (0.0-1.0)
            max_tokens: Maximum tokens in response

        Returns:
            LLMResponse with the assistant's reply

        Raises:
            Exception: If the request fails
        """
        pass

    def _emit_event(self, event_type: str, data: dict[str, Any]) -> None:
        """
        Emit an event to the callback if configured.

        Used for reporting MCP tool invocations in verbose mode.

        Args:
            event_type: Type of event (e.g., "tool_call", "tool_result")
            data: Event data
        """
        if self.event_callback:
            self.event_callback(event_type, data)

    @abstractmethod
    def get_provider_name(self) -> str:
        """
        Get the name of the LLM provider.

        Returns:
            Provider name (e.g., "openai", "anthropic", "gemini")
        """
        pass

    @abstractmethod
    def format_messages(self, messages: list[dict[str, str]]) -> list[dict[str, Any]]:
        """
        Format messages to provider-specific format.

        Converts standard message format to the format expected by the provider.

        Args:
            messages: Messages in standard format [{"role": "user", "content": "..."}]

        Returns:
            Messages in provider-specific format
        """
        pass
