"""Chatbot agent for project Q&A using Claude Agent SDK."""

import json
from pathlib import Path
from typing import AsyncIterator, Optional

from claude_agent_sdk import ClaudeAgentOptions, query


class WikiChatbot:
    """Chatbot for answering questions about a project using Claude Agent SDK."""

    def __init__(self, project_path: Path, wiki_dir: Optional[Path] = None):
        """Initialize chatbot.

        Args:
            project_path: Path to the project
            wiki_dir: Path to .wiki directory (default: project_path/.wiki)
        """
        self.project_path = project_path.resolve()
        self.wiki_dir = (wiki_dir or (project_path / ".wiki")).resolve()
        self.project_root = str(self.project_path)

        # Load wiki context
        self._wiki_context = self._load_wiki_context()

    def _load_wiki_context(self) -> str:
        """Load wiki content as context.

        Returns:
            Combined wiki content as context string
        """
        context_parts = []

        # Try to load cache first
        cache_file = self.wiki_dir / "cache.json"
        if cache_file.exists():
            try:
                cache_data = json.loads(cache_file.read_text(encoding="utf-8"))

                # Add project path
                project_path = cache_data.get("project_path", "")
                context_parts.append(f"# Project Path: {project_path}")
                context_parts.append("")

                # List available pages
                pages = cache_data.get("pages", [])
                if pages:
                    context_parts.append("## Available Wiki Pages:")
                    for page in pages:
                        context_parts.append(f"- {page.get('path')}: {page.get('title')}")
                    context_parts.append("")
            except Exception:
                pass

        # Load all markdown files from wiki directory
        if self.wiki_dir.exists():
            for md_file in sorted(self.wiki_dir.rglob("*.md")):
                try:
                    content = md_file.read_text(encoding="utf-8")
                    rel_path = md_file.relative_to(self.wiki_dir)
                    context_parts.append(f"\n## File: {rel_path}\n")
                    # Include full content for smaller files, summary for larger
                    if len(content) > 5000:
                        # Include first 3000 chars for context
                        context_parts.append(content[:3000])
                        context_parts.append("\n... (truncated)")
                    else:
                        context_parts.append(content)
                except Exception:
                    pass

        return "\n".join(context_parts)

    async def answer(self, question: str) -> AsyncIterator[str]:
        """Answer a question about the project.

        Args:
            question: User's question

        Yields:
            Response chunks (text)
        """
        # System prompt for Q&A
        system_prompt = f"""You are a helpful assistant that answers questions about a software project.

## Project Context
{self._wiki_context}

## Instructions
- Answer questions based on the project context and code
- Use the available tools to read and analyze files when needed
- Provide specific file paths and line numbers when referencing code
- If you're unsure about something, say so
- Be concise but thorough
- Format code examples with proper syntax

## Available Tools
Use Claude Code's built-in tools:
- Read: Read file contents
- Grep: Search for patterns in files
- Glob: Find files by pattern
- ListDirectory: List directory contents"""

        # Configure the agent
        options = ClaudeAgentOptions(
            system_prompt=system_prompt,
            permission_mode="default",
            cwd=self.project_root,
        )

        # Query the agent - collect all text blocks and tool calls
        async for message in query(prompt=question, options=options):
            # Check message type
            message_type = message.__class__.__name__

            if message_type == "AssistantMessage":
                # Assistant messages have content blocks
                if hasattr(message, "content"):
                    for block in message.content:
                        # TextBlock has text attribute
                        if hasattr(block, "text"):
                            yield block.text
                        # ToolUseBlock - show tool usage
                        elif hasattr(block, "name"):
                            tool_name = block.name
                            tool_input = getattr(block, "input", {})
                            # Format tool input for display
                            if isinstance(tool_input, dict):
                                if "file_path" in tool_input:
                                    yield f"\n\n🔧 **Using tool: {tool_name}** `{tool_input.get('file_path', '')}`\n\n"
                                elif "pattern" in tool_input:
                                    yield f"\n\n🔧 **Using tool: {tool_name}** `{tool_input.get('pattern', '')}`\n\n"
                                elif "path" in tool_input:
                                    yield f"\n\n🔧 **Using tool: {tool_name}** `{tool_input.get('path', '')}`\n\n"
                                else:
                                    yield f"\n\n🔧 **Using tool: {tool_name}**\n\n"
                            else:
                                yield f"\n\n🔧 **Using tool: {tool_name}**\n\n"
            elif message_type == "ToolResultMessage":
                # Tool results - show brief status
                if hasattr(message, "content"):
                    yield f"✅ **Tool completed**\n\n"

    async def answer_stream(self, question: str) -> AsyncIterator[dict]:
        """Answer a question with streaming metadata.

        Args:
            question: User's question

        Yields:
            Dict with 'content' and 'done' keys
        """
        content_buffer = ""

        async for chunk in self.answer(question):
            content_buffer += chunk
            yield {"content": chunk, "done": False}

        # Send final done signal
        yield {"content": "", "done": True}


def create_chatbot(project_path: str, wiki_dir: Optional[str] = None) -> WikiChatbot:
    """Create a chatbot instance.

    Args:
        project_path: Path to the project
        wiki_dir: Optional path to wiki directory

    Returns:
        WikiChatbot instance
    """
    return WikiChatbot(Path(project_path), Path(wiki_dir) if wiki_dir else None)
