"""albus tool -- Call a tool directly."""

from __future__ import annotations

import asyncio
import json as _json
from typing import Any

from core.pathways.models.tool import ToolArgs, ToolOutput
from core.tools import get_tool_registry
from server.transport.cli._models import ToolCallArgs
from stdlib.bootstrap import load_stdlib


def cmd_tool(args: ToolCallArgs) -> int:
    """Call a tool directly."""
    if not args.tool_name:
        print("Error: tool name required")
        return 2

    # Parse tool args (--key value or --key=value)
    parsed_args: dict[str, Any] = {}
    i = 0
    raw_args = args.tool_args
    while i < len(raw_args):
        arg = raw_args[i]
        if arg.startswith("--"):
            key = arg[2:]
            if "=" in key:
                k, v = key.split("=", 1)
                parsed_args[k] = _parse_value(v)
            elif i + 1 < len(raw_args) and not raw_args[i + 1].startswith("--"):
                parsed_args[key] = _parse_value(raw_args[i + 1])
                i += 1
            else:
                parsed_args[key] = True
        i += 1

    async def _call() -> int:
        load_stdlib()

        registry = get_tool_registry()
        tool_def = registry.get(args.tool_name)
        handler = tool_def.handler if tool_def else None
        if not handler:
            print(f"Error: Tool '{args.tool_name}' not found")
            print("\nAvailable tools:")
            for name in registry.names()[:20]:
                print(f"  {name}")
            if len(registry) > 20:
                print(f"  ... and {len(registry) - 20} more (use 'albus list tools')")
            return 1

        try:
            result = await handler(ToolArgs(**parsed_args), None)
            if isinstance(result, ToolOutput):
                if result.success:
                    print("\u2705 Success")
                    if result.data:
                        if isinstance(result.data, dict):
                            for k, v in result.data.items():
                                print(
                                    f"  {k}: {_json.dumps(v, indent=2, default=str) if isinstance(v, (dict, list)) else v}"
                                )
                        else:
                            print(f"  {result.data}")
                else:
                    print(f"\u274c Error: {result.error}")
                    return 1
            elif isinstance(result, dict):
                if result.get("success"):
                    for k, v in result.items():
                        if k not in ("success",):
                            print(
                                f"{k}: {_json.dumps(v, indent=2, default=str) if isinstance(v, (dict, list)) else v}"
                            )
                else:
                    print(f"Error: {result.get('error', 'Unknown error')}")
                    return 1
            else:
                print(result)
            return 0
        except Exception as e:
            print(f"Error: {e}")
            return 1

    return asyncio.run(_call())


def _parse_value(v: str) -> Any:
    """Parse a CLI value to appropriate type."""
    if v.lower() == "true":
        return True
    if v.lower() == "false":
        return False
    try:
        return int(v)
    except ValueError:
        pass
    try:
        return float(v)
    except ValueError:
        pass
    try:
        return _json.loads(v)
    except _json.JSONDecodeError:
        pass
    return v
