"""CLI commands for reasoning: think."""

from __future__ import annotations

import typer
from rich.console import Console

from engram.utils import run_async

console = Console()


def register(app: typer.Typer, get_config) -> None:
    """Register reasoning commands on the main Typer app."""

    def _get_engine():
        from engram.episodic.store import EpisodicStore
        from engram.providers.registry import ProviderRegistry
        from engram.reasoning.engine import ReasoningEngine
        from engram.semantic import create_graph
        cfg = get_config()
        try:
            episodic = EpisodicStore(
                cfg.episodic, cfg.embedding, on_remember_hook=cfg.hooks.on_remember
            )
        except RuntimeError as e:
            if "already accessed" in str(e):
                # Server is running — use HTTP proxy for think
                return _HttpThinkProxy(cfg)
            raise
        graph = create_graph(cfg.semantic)
        registry = ProviderRegistry()
        registry.load_from_config(cfg)
        providers = registry.get_active()
        return ReasoningEngine(
            episodic, graph, model=cfg.llm.model,
            on_think_hook=cfg.hooks.on_think, providers=providers,
            disable_thinking=cfg.llm.disable_thinking,
        )

    class _HttpThinkProxy:
        """Proxy think/ask to running HTTP server."""
        def __init__(self, cfg):
            self._base = f"http://{cfg.serve.host}:{cfg.serve.port}/api/v1"

        async def think(self, query, **kwargs):
            import httpx
            async with httpx.AsyncClient(timeout=60) as client:
                resp = await client.post(f"{self._base}/think", json={"query": query})
                return resp.json()

    @app.command()
    def ask(query: str = typer.Argument(..., help="Any question or search query")):
        """Smart query — auto-routes to recall or think based on intent.

        Why/how/explain questions → think (LLM reasoning).
        Simple lookups → recall (vector search).
        """
        from engram.providers.router import classify_intent
        intent = classify_intent(query)
        if intent == "think":
            console.print("[dim]intent: think[/dim]")
            engine = _get_engine()
            result = run_async(engine.think(query))
            if result.get("degraded"):
                console.print("[yellow][degraded mode][/yellow]")
            console.print(result["answer"])
        else:
            console.print("[dim]intent: recall[/dim]")
            from engram.cli.episodic import _get_episodic
            from engram.providers.registry import ProviderRegistry
            from engram.providers.router import federated_search
            cfg = get_config()
            store = _get_episodic(get_config)
            results = run_async(store.search(query, limit=5))
            # Federated
            registry = ProviderRegistry()
            registry.load_from_config(cfg)
            providers = registry.get_active()
            if providers:
                for r in run_async(federated_search(query, providers, limit=3)):
                    console.print(f"[magenta]\\[{r.source}][/magenta] {r.content[:300]}")
            if not results:
                console.print("[dim]No memories found.[/dim]")
                return
            for mem in results:
                ts = mem.timestamp.strftime("%Y-%m-%d %H:%M")
                console.print(f"[cyan][{ts}][/cyan] ({mem.memory_type.value}) {mem.content}")

    @app.command()
    def think(question: str = typer.Argument(..., help="Question to reason about")):
        """Combined reasoning across both memories."""
        engine = _get_engine()
        result = run_async(engine.think(question))
        if result.get("degraded"):
            console.print("[yellow][degraded mode][/yellow]")
        console.print(result["answer"])
