"""Register OpenFang Hands as MCP tools in Timmy's tool registry.

Each OpenFang Hand becomes a callable MCP tool that personas can use
during task execution.  The mapping ensures the right personas get
access to the right hands:

    Mace (Security)  → collector (OSINT), browser
    Seer (Analytics) → predictor, researcher
    Echo (Research)  → researcher, browser, collector
    Helm (DevOps)    → browser
    Lead hand        → available to all personas via direct request

Call ``register_openfang_tools()`` during app startup (after config
is loaded) to populate the tool registry.
"""

import logging
from typing import Any

from infrastructure.openfang.client import OPENFANG_HANDS, openfang_client

try:
    from mcp.schemas.base import create_tool_schema
except ImportError:

    def create_tool_schema(**kwargs):
        return kwargs


logger = logging.getLogger(__name__)

# ── Tool schemas ─────────────────────────────────────────────────────────────

_HAND_SCHEMAS: dict[str, dict] = {
    "browser": create_tool_schema(
        name="openfang_browser",
        description=(
            "Web automation via OpenFang's Browser hand. "
            "Navigates URLs, extracts content, fills forms. "
            "Includes mandatory purchase confirmation gates."
        ),
        parameters={
            "url": {"type": "string", "description": "URL to navigate to"},
            "instruction": {
                "type": "string",
                "description": "What to do on the page",
            },
        },
        required=["url"],
    ),
    "collector": create_tool_schema(
        name="openfang_collector",
        description=(
            "OSINT intelligence and continuous monitoring via OpenFang's "
            "Collector hand. Gathers public information on targets."
        ),
        parameters={
            "target": {
                "type": "string",
                "description": "Target to investigate (domain, org, person)",
            },
            "depth": {
                "type": "string",
                "description": "Collection depth: shallow | standard | deep",
                "default": "shallow",
            },
        },
        required=["target"],
    ),
    "predictor": create_tool_schema(
        name="openfang_predictor",
        description=(
            "Superforecasting with calibrated reasoning via OpenFang's "
            "Predictor hand. Produces probability estimates with reasoning."
        ),
        parameters={
            "question": {
                "type": "string",
                "description": "Forecasting question to evaluate",
            },
            "horizon": {
                "type": "string",
                "description": "Time horizon: 1d | 1w | 1m | 3m | 1y",
                "default": "1w",
            },
        },
        required=["question"],
    ),
    "lead": create_tool_schema(
        name="openfang_lead",
        description=(
            "Prospect discovery and ICP-based qualification via OpenFang's "
            "Lead hand. Finds and scores potential leads."
        ),
        parameters={
            "icp": {
                "type": "string",
                "description": "Ideal Customer Profile description",
            },
            "max_results": {
                "type": "integer",
                "description": "Maximum leads to return",
                "default": 10,
            },
        },
        required=["icp"],
    ),
    "twitter": create_tool_schema(
        name="openfang_twitter",
        description=(
            "Social account management via OpenFang's Twitter hand. "
            "Includes approval gates for sensitive actions."
        ),
        parameters={
            "action": {
                "type": "string",
                "description": "Action: post | reply | search | analyze",
            },
            "content": {
                "type": "string",
                "description": "Content for the action",
            },
        },
        required=["action", "content"],
    ),
    "researcher": create_tool_schema(
        name="openfang_researcher",
        description=(
            "Deep autonomous research with source verification via "
            "OpenFang's Researcher hand. Produces cited reports."
        ),
        parameters={
            "topic": {
                "type": "string",
                "description": "Research topic or question",
            },
            "depth": {
                "type": "string",
                "description": "Research depth: quick | standard | deep",
                "default": "standard",
            },
        },
        required=["topic"],
    ),
    "clip": create_tool_schema(
        name="openfang_clip",
        description=(
            "Video processing and social media publishing via OpenFang's "
            "Clip hand. Edits, captions, and publishes video content."
        ),
        parameters={
            "source": {
                "type": "string",
                "description": "Source video path or URL",
            },
            "instruction": {
                "type": "string",
                "description": "What to do with the video",
            },
        },
        required=["source"],
    ),
}

# Map personas to the OpenFang hands they should have access to
PERSONA_HAND_MAP: dict[str, list[str]] = {
    "echo": ["researcher", "browser", "collector"],
    "seer": ["predictor", "researcher"],
    "mace": ["collector", "browser"],
    "helm": ["browser"],
    "forge": ["browser", "researcher"],
    "quill": ["researcher"],
    "pixel": ["clip", "browser"],
    "lyra": [],
    "reel": ["clip"],
}


def _make_hand_handler(hand_name: str):
    """Create an async handler that delegates to the OpenFang client."""

    async def handler(**kwargs: Any) -> str:
        result = await openfang_client.execute_hand(hand_name, kwargs)
        if result.success:
            return result.output
        return f"[OpenFang {hand_name} error] {result.error}"

    handler.__name__ = f"openfang_{hand_name}"
    handler.__doc__ = _HAND_SCHEMAS.get(hand_name, {}).get(
        "description", f"OpenFang {hand_name} hand"
    )
    return handler


def register_openfang_tools() -> int:
    """Register all OpenFang Hands as MCP tools.

    Returns the number of tools registered.
    """
    try:
        from mcp.registry import tool_registry
    except ImportError:
        logger.warning("MCP registry not available — skipping OpenFang tool registration")
        return 0

    count = 0
    for hand_name in OPENFANG_HANDS:
        schema = _HAND_SCHEMAS.get(hand_name)
        if not schema:
            logger.warning("No schema for OpenFang hand: %s", hand_name)
            continue

        tool_name = f"openfang_{hand_name}"
        handler = _make_hand_handler(hand_name)

        tool_registry.register(
            name=tool_name,
            schema=schema,
            handler=handler,
            category="openfang",
            tags=["openfang", hand_name, "vendor"],
            source_module="infrastructure.openfang.tools",
            requires_confirmation=(hand_name in ("twitter",)),
        )
        count += 1

    logger.info("Registered %d OpenFang tools in MCP registry", count)
    return count


def get_hands_for_persona(persona_id: str) -> list[str]:
    """Return the OpenFang tool names available to a persona."""
    hand_names = PERSONA_HAND_MAP.get(persona_id, [])
    return [f"openfang_{h}" for h in hand_names]
