from collections.abc import Sequence

try:
    from anthropic import AsyncAnthropic
    from anthropic.types import MessageParam, TextBlock, ToolParam, ToolUseBlock

    from haiku.rag.client import HaikuRAG
    from haiku.rag.qa.base import QuestionAnswerAgentBase

    class QuestionAnswerAnthropicAgent(QuestionAnswerAgentBase):
        def __init__(self, client: HaikuRAG, model: str = "claude-3-5-haiku-20241022"):
            super().__init__(client, model or self._model)
            self.tools: Sequence[ToolParam] = [
                ToolParam(
                    name="search_documents",
                    description="Search the knowledge base for relevant documents",
                    input_schema={
                        "type": "object",
                        "properties": {
                            "query": {
                                "type": "string",
                                "description": "The search query to find relevant documents",
                            },
                            "limit": {
                                "type": "integer",
                                "description": "Maximum number of results to return",
                                "default": 3,
                            },
                        },
                        "required": ["query"],
                    },
                )
            ]

        async def answer(self, question: str) -> str:
            anthropic_client = AsyncAnthropic()

            messages: list[MessageParam] = [{"role": "user", "content": question}]

            max_rounds = 5  # Prevent infinite loops

            for _ in range(max_rounds):
                response = await anthropic_client.messages.create(
                    model=self._model,
                    max_tokens=4096,
                    system=self._system_prompt,
                    messages=messages,
                    tools=self.tools,
                    temperature=0.0,
                )

                if response.stop_reason == "tool_use":
                    messages.append({"role": "assistant", "content": response.content})

                    # Process tool calls
                    tool_results = []
                    for content_block in response.content:
                        if isinstance(content_block, ToolUseBlock):
                            if content_block.name == "search_documents":
                                args = content_block.input
                                query = (
                                    args.get("query", question)
                                    if isinstance(args, dict)
                                    else question
                                )
                                limit = (
                                    int(args.get("limit", 3))
                                    if isinstance(args, dict)
                                    else 3
                                )

                                search_results = await self._client.search(
                                    query, limit=limit
                                )

                                context_chunks = []
                                for chunk, score in search_results:
                                    context_chunks.append(
                                        f"Content: {chunk.content}\nScore: {score:.4f}"
                                    )

                                context = "\n\n".join(context_chunks)

                                tool_results.append(
                                    {
                                        "type": "tool_result",
                                        "tool_use_id": content_block.id,
                                        "content": context,
                                    }
                                )

                    if tool_results:
                        messages.append({"role": "user", "content": tool_results})
                else:
                    # No tool use, return the response
                    if response.content:
                        first_content = response.content[0]
                        if isinstance(first_content, TextBlock):
                            return first_content.text
                    return ""

            # If we've exhausted max rounds, return empty string
            return ""

except ImportError:
    pass
