"""Claude Agent SDK backend for ORBIT Assist (optional).

Provides more sophisticated reasoning via Claude with bash, file, and
ORBIT-specific tools. Activated with: orbit assist --backend claude

Requires: pip install claude-agent-sdk
Requires: ANTHROPIC_API_KEY environment variable
"""

from __future__ import annotations

import logging
import os

logger = logging.getLogger(__name__)


def is_available() -> bool:
    """Check if Claude Agent SDK is installed and configured."""
    if not os.environ.get("ANTHROPIC_API_KEY"):
        return False
    try:
        import claude_code_sdk  # noqa: F401

        return True
    except ImportError:
        return False


class ClaudeBackend:
    """Claude Agent SDK backend for orbit assist.

    Uses Claude's native agentic loop with bash/read/write tools
    plus ORBIT-specific custom tools.
    """

    def __init__(self, system_prompt: str):
        self.system_prompt = system_prompt
        self._validate()

    def _validate(self) -> None:
        if not os.environ.get("ANTHROPIC_API_KEY"):
            raise RuntimeError(
                "ANTHROPIC_API_KEY required for Claude backend.\n"
                "Set it with: export ANTHROPIC_API_KEY=sk-..."
            )
        try:
            import claude_code_sdk  # noqa: F401
        except ImportError:
            raise RuntimeError(
                "Claude Agent SDK not installed.\n"
                "Install with: pip install claude-code-sdk"
            )

    def run_turn(
        self,
        user_message: str,
        system_prompt: str,
        on_tool_call: callable | None = None,
    ) -> str:
        """Run a turn using Claude Agent SDK.

        Args:
            user_message: The user's input.
            system_prompt: Full system prompt with context.
            on_tool_call: Optional callback for tool call notifications.

        Returns:
            Final text response.
        """
        import asyncio

        from claude_code_sdk import ClaudeCodeSDKClient, Query

        client = ClaudeCodeSDKClient()

        # Prepend system prompt as context in the user message
        full_message = f"{system_prompt}\n\n---\n\nUser request: {user_message}"

        response_text = ""
        try:
            loop = asyncio.new_event_loop()
            asyncio.set_event_loop(loop)
            try:
                response_text = loop.run_until_complete(
                    self._async_run(client, full_message, on_tool_call)
                )
            finally:
                loop.close()
        except Exception as e:
            logger.debug("Claude backend error: %s", e)
            response_text = f"Claude backend error: {e}"

        return response_text

    async def _async_run(
        self, client: object, message: str, on_tool_call: callable | None
    ) -> str:
        """Async runner for Claude SDK."""
        from claude_code_sdk import ClaudeCodeSDKClient, Query

        response_parts: list[str] = []
        async for msg in client.process_query(
            Query(
                prompt=message,
                options={
                    "allowedTools": ["Bash", "Read", "Glob", "Grep"],
                    "maxTurns": 15,
                },
            )
        ):
            if hasattr(msg, "content") and isinstance(msg.content, str):
                response_parts.append(msg.content)
            elif hasattr(msg, "type") and msg.type == "tool_use":
                if on_tool_call:
                    on_tool_call(msg.name, getattr(msg, "input", {}), None)

        return "\n".join(response_parts) if response_parts else "No response from Claude."

    def reset(self) -> None:
        """Reset state (Claude SDK is stateless per query)."""
        pass
