"""Lightweight tool-selection decider using GPT-5-nano structured output."""

from __future__ import annotations

from openai import OpenAI
from pydantic import BaseModel

from .errors import DeciderError

DECIDER_MODEL = "gpt-5-nano"

DECIDER_PROMPT = """\
You are a tool-selection filter. Given the user's message and a list of \
available tools (name + description), return the tool names that are \
relevant to fulfilling the request.

If no tools are needed (e.g. the user is just chatting), return an empty list.

Be selective about which Service/MCP is needed, but generous about which tools are needed. 

If two different tools or MCPs overlap a request, return both.
For example, if the user asks to read a Github repo, and you have both DeepWiki (Github repo reading tool) and Github MCP available, select both.
"""

client = OpenAI()


class DeciderOutput(BaseModel):
    """Structured output from the decider model."""
    chosen_tools: list[str]


def decide_tools(
    user_input: str,
    available_tools: list[dict],
) -> list[str]:
    """Use GPT-5-nano to decide which tools are relevant for the user's input.

    Args:
        user_input: The user's message / prompt.
        available_tools: List of ``{"name": str, "description": str}`` dicts.

    Returns:
        List of tool names deemed relevant (empty if no tools needed).
    """
    if not available_tools:
        return []

    tool_list = "\n".join(
        f"- {t['name']}: {t['description']}" for t in available_tools
    )

    try:
        response = client.responses.parse(
            model=DECIDER_MODEL,
            instructions=DECIDER_PROMPT,
            input=f"User message: {user_input}\n\nAvailable tools:\n{tool_list}",
            text_format=DeciderOutput,
        )
    except Exception as exc:
        raise DeciderError(
            f"Tool selection failed: {exc}. "
            f"This uses OpenAI's API under the hood — check that OPENAI_API_KEY is set and valid."
        ) from exc

    if response.output_parsed is None:
        raise DeciderError(
            "Tool selection model returned an unparseable response. Retrying may help."
        )

    chosen = response.output_parsed.chosen_tools

    # Guard against hallucinated tool names
    valid_names = {t["name"] for t in available_tools}
    return [name for name in chosen if name in valid_names]
