from lmos_openai_types import (
    CreateChatCompletionRequest,
    CreateChatCompletionResponse,
    ChatCompletionRequestMessage,
)
from urllib.parse import urlparse

from .genericHttpxClient import get_client
from .utils import call_tool, chat_completion_add_tools
from mcp_bridge.mcp_clients.McpClientManager import ClientManager
from mcp_bridge.tool_mappers import mcp2openai
from mcp_bridge.config import config
from loguru import logger
import json


async def chat_completions(
    request: CreateChatCompletionRequest,
    api_key: str = None,
) -> CreateChatCompletionResponse:
    """performs a chat completion using the inference server"""
    request = await chat_completion_add_tools(request)
    client = get_client(api_key)

    while True:
        # logger.debug(request.model_dump_json())

        text = (
            await client.post(
                "/chat/completions",
                #content=request.model_dump_json(
                #    exclude_defaults=True, exclude_none=True, exclude_unset=True
                #),
                json=request.model_dump(exclude_defaults=True, exclude_none=True, exclude_unset=True),
            )
        ).text
        logger.debug(text)
        try:
            response = CreateChatCompletionResponse.model_validate_json(text)
        except Exception as e:
            logger.error(f"Error parsing response: {text}")
            logger.error(e)
            return

        msg = response.choices[0].message
        msg = ChatCompletionRequestMessage(
            role="assistant",
            content=msg.content,
            tool_calls=msg.tool_calls,
        )  # type: ignore
        request.messages.append(msg)

        logger.debug(f"finish reason: {response.choices[0].finish_reason}")
        if response.choices[0].finish_reason.value in ["stop", "length"]:
            logger.debug("no tool calls found")
            return response

        logger.debug("tool calls found")
        for tool_call in response.choices[0].message.tool_calls.root:
            logger.info(
                f"tool call: {tool_call.function.name} arguments: {json.loads(tool_call.function.arguments)}"
            )

            # FIXME: this can probably be done in parallel using asyncio gather
            tool_call_result = await call_tool(
                tool_call.function.name, tool_call.function.arguments
            )
            if tool_call_result is None:
                continue

            logger.debug(
                f"tool call result for {tool_call.function.name}: {tool_call_result.model_dump()}"
            )

            logger.debug(f"tool call result content: {tool_call_result.content}")

            # Check if we're using Anthropic API
            def is_anthropic_endpoint(base_url: str) -> bool:
                """Detect if we're using Anthropic's API"""
                parsed_url = urlparse(base_url)
                return "anthropic.com" in parsed_url.netloc

            if is_anthropic_endpoint(config.inference_server.base_url):
                # For Anthropic, use a simple string content
                text_parts = [part.text for part in filter(lambda x: x.type == "text", tool_call_result.content)]
                content_str = " ".join(text_parts) if text_parts else "the tool call result is empty"
                request.messages.append(
                    ChatCompletionRequestMessage.model_validate(
                        {
                            "role": "tool",
                            "content": content_str,  # Simple string for Anthropic
                            "tool_call_id": tool_call.id,
                        }
                    )
                )
            else:
                # For other providers, keep the rich format
                tools_content = [
                    {"type": "text", "text": part.text}
                    for part in filter(lambda x: x.type == "text", tool_call_result.content)
                ]
                if len(tools_content) == 0:
                    tools_content = [
                        {"type": "text", "text": "the tool call result is empty"}
                    ]
                request.messages.append(
                    ChatCompletionRequestMessage.model_validate(
                        {
                            "role": "tool",
                            "content": str(tools_content),
                            "tool_call_id": tool_call.id,
                        }
                    )
                )

            logger.debug("sending next iteration of chat completion request")
