"""
Gemini MCP Adapter

Integrates Google Gemini models with the HoneyDB MCP server using
the fastmcp client library.
"""

from typing import Any, Callable

from fastmcp import Client as FastMcpClient
from google import genai

from honeydb_ai.domain.models import LLMResponse
from honeydb_ai.infrastructure.mcp.base import MCPAdapter
from honeydb_ai.utils.logging import get_logger


class GeminiMCPAdapter(MCPAdapter):
    """
    Gemini adapter with MCP server integration.

    Uses fastmcp.Client to connect to the HoneyDB MCP server and
    passes the MCP session to Gemini's tools configuration.

    Reference: Original implementation in llm_client.py:132-152
    """

    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 Gemini MCP adapter.

        Args:
            api_key: Google Gemini API key
            mcp_server_url: HoneyDB MCP server URL (e.g., https://honeydb.ai/sse/)
            honeydb_api_id: HoneyDB API ID
            honeydb_api_key: HoneyDB API key
            event_callback: Optional callback for tool invocation events
        """
        super().__init__(api_key, mcp_server_url, honeydb_api_id, honeydb_api_key, event_callback)
        self.client = genai.Client(api_key=api_key)
        self.logger = get_logger()

        # Configure FastMCP client for HoneyDB server
        self.mcp_config = {
            "mcpServers": {
                "honeydb": {
                    "transport": "sse",
                    "url": self.mcp_server_url,
                    "headers": {
                        "X-HoneyDb-ApiId": self.honeydb_api_id,
                        "X-HoneyDb-ApiKey": self.honeydb_api_key,
                    },
                }
            }
        }

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

        Uses fastmcp.Client to establish connection to MCP server,
        then passes the MCP session to Gemini's tools configuration.

        Args:
            messages: Messages in Gemini format [{"role": "user|model", "parts": [...]}]
            model: Gemini model (e.g., "gemini-2.0-flash")
            temperature: Sampling temperature
            max_tokens: Maximum response tokens

        Returns:
            LLMResponse with assistant's reply

        Raises:
            Exception: If the API call fails
        """
        try:
            self.logger.debug(f"Sending request to Gemini model: {model}")
            self._emit_event("request_started", {"model": model, "provider": "gemini"})

            # Create MCP client and connect to server
            mcp_client = FastMcpClient(self.mcp_config)

            # Use async context manager to maintain connection during request
            async with mcp_client:
                # Call Gemini with MCP session as tools
                response = await self.client.aio.models.generate_content(
                    model=model,
                    config=genai.types.GenerateContentConfig(
                        tools=[mcp_client.session],
                        temperature=temperature,
                        max_output_tokens=max_tokens,
                    ),
                    contents=messages,
                )

                # Extract response text
                content = response.text

            self.logger.debug(f"Received response from Gemini: {len(content)} characters")
            self._emit_event("response_received", {
                "model": model,
                "provider": "gemini",
                "content_length": len(content)
            })

            # Create LLMResponse
            return LLMResponse(
                content=content,
                model=model,
                finish_reason=getattr(response, "finish_reason", None),
                usage={},  # Usage info structure varies in Gemini
                metadata={
                    "provider": "gemini",
                    "mcp_enabled": True,
                }
            )

        except Exception as e:
            self.logger.error(f"Gemini API error: {e}")
            raise

    def get_provider_name(self) -> str:
        """Get provider name."""
        return "gemini"

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

        Gemini uses:
        - "user" and "model" roles (not "assistant")
        - "parts" array with "text" objects

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

        Returns:
            Messages in Gemini format [{"role": "user|model", "parts": [{"text": "..."}]}]
        """
        formatted = []
        for msg in messages:
            role = msg["role"]
            # Convert "assistant" to "model" for Gemini
            if role == "assistant":
                role = "model"
            # Skip system messages (Gemini doesn't support them in history)
            elif role == "system":
                continue

            formatted.append({
                "role": role,
                "parts": [{"text": msg["content"]}]
            })

        return formatted
