// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

import type { JSXElement } from "@coreai-ds/react-components";
import { Markdown } from "@coreai-ds/react-components";
import * as React from 'react';

const largeExample = `
#### Create Agent with Function Call

You can enhance your Agents by defining callback functions as function tools. These can be provided to \`createAgent\` via the combination of \`tools\` and \`toolResources\`. Only the function definitions and descriptions are provided to \`createAgent\`, without the implementations. The \`Run\` or \`event handler of stream\` will raise a \`requires_action\` status based on the function definitions. Your code must handle this status and call the appropriate functions.

Here is an example:

\`\`\`ts
import {
  FunctionToolDefinition,
  ToolUtility,
  RequiredToolCallOutput,
  FunctionToolDefinitionOutput,
  ToolOutput,
} from "@azure/ai-projects";

class FunctionToolExecutor {
  private functionTools: {
    func: Function;
    definition: FunctionToolDefinition;
  }[];
  constructor() {
    this.functionTools = [
      {
        func: this.getUserFavoriteCity,
        ...ToolUtility.createFunctionTool({
          name: "getUserFavoriteCity",
          description: "Gets the user's favorite city.",
          parameters: {},
        }),
      },
      {
        func: this.getCityNickname,
        ...ToolUtility.createFunctionTool({
          name: "getCityNickname",
          description: "Gets the nickname of a city, e.g. 'LA' for 'Los Angeles, CA'.",
          parameters: {
            type: "object",
            properties: {
              location: { type: "string", description: "The city and state, e.g. Seattle, Wa" },
            },
          },
        }),
      },
      {
        func: this.getWeather,
        ...ToolUtility.createFunctionTool({
          name: "getWeather",
          description: "Gets the weather for a location.",
          parameters: {
            type: "object",
            properties: {
              location: { type: "string", description: "The city and state, e.g. Seattle, Wa" },
              unit: { type: "string", enum: ["c", "f"] },
            },
          },
        }),
      },
    ];
  }
  private getUserFavoriteCity(): {} {
    return { location: "Seattle, WA" };
  }
  private getCityNickname(location: string): {} {
    return { nickname: "The Emerald City" };
  }
  private getWeather(location: string, unit: string): {} {
    return { weather: unit === "f" ? "72f" : "22c" };
  }
  public invokeTool(
    toolCall: RequiredToolCallOutput & FunctionToolDefinitionOutput,
  ): ToolOutput | undefined {
    console.log(\`Function tool call - \${toolCall.function.name}\`);
    const args = [];
    if (toolCall.function.parameters) {
      try {
        const params = JSON.parse(toolCall.function.parameters);
        for (const key in params) {
          if (Object.prototype.hasOwnProperty.call(params, key)) {
            args.push(params[key]);
          }
        }
      } catch (error) {
        console.error(\`Failed to parse parameters: \${toolCall.function.parameters}\`, error);
        return undefined;
      }
    }
    const result = this.functionTools
      .find((tool) => tool.definition.function.name === toolCall.function.name)
      ?.func(...args);
    return result
      ? {
          toolCallId: toolCall.id,
          output: JSON.stringify(result),
        }
      : undefined;
  }
  public getFunctionDefinitions(): FunctionToolDefinition[] {
    return this.functionTools.map((tool) => {
      return tool.definition;
    });
  }
}
const functionToolExecutor = new FunctionToolExecutor();
const functionTools = functionToolExecutor.getFunctionDefinitions();
const agent = await client.agents.createAgent("gpt-4o", {
  name: "my-agent",
  instructions:
    "You are a weather bot. Use the provided functions to help answer questions. Customize your responses to the user's preferences as much as possible and use friendly nicknames for cities whenever possible.",
  tools: functionTools,
});
console.log(\`Created agent, agent ID: \${agent.id}\`);
\`\`\`
`;

export const LargeExample = (): JSXElement => <Markdown content={largeExample}/>;

export default LargeExample;
