/**
 * Copyright 2022-2025 Theai, Inc. dba Inworld AI
 */

#pragma once

#include "CoreMinimal.h"
#include "UObject/Object.h"

#include "InworldMCPTypes.generated.h"

/**
 * @struct FInworldMCPHttpConfig
 * @brief Configuration for creating an MCP client that communicates over HTTP.
 */
USTRUCT(BlueprintType)
struct FInworldMCPHttpConfig
{
	GENERATED_BODY()

	/** The API key for authentication. */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Inworld|MCP")
	FString APIKey;

	/** Default timeout for the request. */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Inworld|MCP")
	FTimespan DefaultTimeout = FTimespan::MaxValue();
};

/**
 * @struct FInworldParagonApiConfig
 * @brief Configuration for creating an MCP client that communicates with the Paragon API.
 */
USTRUCT(BlueprintType)
struct FInworldParagonApiConfig
{
	GENERATED_BODY()

	/** The JWT token for authentication. */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Inworld|MCP")
	FString JWTToken;

	/** Default timeout for the request. */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Inworld|MCP")
	FTimespan DefaultTimeout = FTimespan::MaxValue();
};

/**
 * @struct FInworldMCPStudioConfig
 * @brief Configuration for creating an MCP client that communicates over stdio.
 */
USTRUCT(BlueprintType)
struct FInworldMCPStudioConfig
{
	GENERATED_BODY()

	/** Environment variables to set for the subprocess. */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Inworld|MCP")
	TMap<FString, FString> Environment;
};

UENUM(BlueprintType)
enum class EInworldMCPTransport : uint8
{
	Http,
	Studio,
	Paragon,
};

/**
 * @struct FInworldMCPSessionCreationConfig
 * @brief Configuration for creating an MCP session.
 */
USTRUCT(BlueprintType)
struct FInworldMCPSessionCreationConfig
{
	GENERATED_BODY()

	/** The transport protocol to use (e.g., "http", "stdio"). */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Inworld|MCP")
	FString Transport;

	/** The endpoint for the MCP service. */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Inworld|MCP")
	FString Endpoint;

	/** Determines which config value we will use. */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Inworld|MCP")
	EInworldMCPTransport TransportType{EInworldMCPTransport::Http};

	/** Transport-specific configuration. */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Inworld|MCP",
		Meta = (EditCondition = "TransportType == EInworldMCPTransport::Http", EditConditionHides))
	FInworldMCPHttpConfig HttpTransportConfig;

	/** Transport-specific configuration. */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Inworld|MCP",
		Meta = (EditCondition = "TransportType == EInworldMCPTransport::Studio", EditConditionHides))
	FInworldMCPStudioConfig StudioTransportConfig;

	/** Transport-specific configuration. */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Inworld|MCP",
		Meta = (EditCondition = "TransportType == EInworldMCPTransport::Paragon", EditConditionHides))
	FInworldParagonApiConfig ParagonTransportConfig;
};

/**
 * @struct FInworldMCPClientCreationConfig
 * @brief Configuration for creating an MCP client.
 */
USTRUCT(BlueprintType)
struct FInworldMCPClientCreationConfig
{
	GENERATED_BODY()

	/** The session configuration. */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Inworld|MCP")
	FInworldMCPSessionCreationConfig SessionConfig;
};

/**
 * @struct FInworldMCPListToolsNodeExecutionConfig
 * @brief Runtime configuration for the InworldNode_MCPListTools that is used during execution.
 */
USTRUCT(BlueprintType)
struct FInworldMCPListToolsNodeExecutionConfig
{
	GENERATED_BODY()

	/** The ID of the MCP component to retrieve from ComponentRegistry. */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Inworld|MCP")
	FString MCPComponentID;
};

/**
 * @struct FInworldMCPCallToolNodeExecutionConfig
 * @brief Runtime configuration for the InworldNode_MCPCallTool that is used during execution.
 */
USTRUCT(BlueprintType)
struct FInworldMCPCallToolNodeExecutionConfig
{
	GENERATED_BODY()

	/** The ID of the MCP component to retrieve from ComponentRegistry. */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Inworld|MCP")
	FString MCPComponentID;
};

/**
 * @struct Tool
 * @brief Tool represents a tool that the model may call.
 *
 * Tools allow models to call functions to perform actions.
 *
 * @param name
 * The name of the function to be called.
 *
 * @param description
 * A description of what the function does, used by the model to choose
 * when and how to call the function.
 *
 * @param properties
 * The parameters the function accepts, described as a JSON schema.
 */
USTRUCT(BlueprintType)
struct FInworldTool
{
	GENERATED_BODY()

	/** The name of the function to be called. */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Inworld|MCP")
	FString Name;

	/** A description of what the function does. */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Inworld|MCP")
	FString Description;

	/** The parameters the function accepts, described as a JSON schema. */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Inworld|MCP")
	FString Properties;
};

/**
 * @struct FInworldToolCall
 * @brief ToolCall represents a tool call made by the model.
 *
 * Tool calls allow models to use functions to interact with external systems
 * or perform specific operations during generation.
 */
USTRUCT(BlueprintType)
struct FInworldToolCall
{
	GENERATED_BODY()

	/** A unique identifier for the tool call. */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Inworld|MCP")
	FString Id;

	/** The name of the tool to be called. */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Inworld|MCP")
	FString Name;

	/** The arguments for the tool call. It is a JSON string. */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Inworld|MCP")
	FString Args;
};
