"""A stand-in model, so this course runs in your browser with no API key.

The Agents SDK talks to a model through one method: get_response. Anything
that provides it is a model as far as the SDK is concerned, so this class is
a real one. The only fake part is how it decides, which is two rules you can
read.
"""
import json

from agents.items import ModelResponse
from agents.models.interface import Model
from agents.usage import Usage
from openai.types.responses import (
    ResponseFunctionToolCall,
    ResponseOutputMessage,
    ResponseOutputText,
)


def say(text):
    """Wrap plain text in the message shape the SDK expects back."""
    return ResponseOutputMessage(
        id="msg_1",
        role="assistant",
        status="completed",
        type="message",
        content=[ResponseOutputText(text=text, type="output_text", annotations=[])],
    )


def call(tool_name, **args):
    """Ask for a tool instead of answering."""
    return ResponseFunctionToolCall(
        id="fc_1",
        call_id="call_1",
        name=tool_name,
        arguments=json.dumps(args),
        type="function_call",
    )


class PretendModel(Model):
    async def get_response(self, system_instructions, input, model_settings, tools,
                           output_schema, handoffs, tracing, **kwargs):
        asked = input if isinstance(input, str) else json.dumps(input)
        already_used_a_tool = "call_1" in asked
        wants_lookup = tools and not already_used_a_tool and "A17" in asked
        item = call(tools[0].name, order_id="A17") if wants_lookup else say(
            "Order A17 shipped on 3 March."
        )
        return ModelResponse(output=[item], usage=Usage(), response_id=None)

    async def stream_response(self, *args, **kwargs):
        raise NotImplementedError("The stand-in model does not stream.")
