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

#pragma once
#include "Primitives/TextEmbedder/InworldTextEmbedding.h"

#include "InworldIntentTypes.generated.h"

INWORLDRUNTIME_API DECLARE_LOG_CATEGORY_EXTERN(LogInworldIntent, Log, All);

/**
 * @struct FInworldIntentMatch
 * @brief Represents a matched intent with its confidence score.
 *
 * This structure contains information about an intent that was matched
 * during intent recognition, including the intent identifier and the
 * confidence score of the match.
 */
USTRUCT(BlueprintType)
struct FInworldIntentMatch
{
	GENERATED_BODY()

	/** The unique identifier of the matched intent */
	UPROPERTY(BlueprintReadOnly, VisibleAnywhere, Category = "Inworld|Intent",
		Meta = (ToolTip = "The unique identifier of the matched intent"))
	FName IntentId;

	/** The confidence score of the intent match (0.0 to 1.0) */
	UPROPERTY(BlueprintReadOnly, VisibleAnywhere, Category = "Inworld|Intent",
		Meta = (ToolTip = "The confidence score of the intent match (0.0 to 1.0)"))
	float Score{0.f};

	bool operator<(const FInworldIntentMatch& Other) const
	{
		return Score < Other.Score;
	}
};

/**
 * @struct FInworldLLMMatcherConfig
 * @brief Configuration for LLM-based intent matching.
 *
 * This structure defines parameters for using Large Language Models to enhance
 * intent matching, including prompt templates and embedding similarity settings.
 */
USTRUCT(BlueprintType)
struct FInworldLLMMatcherConfig
{
	GENERATED_BODY()

	/** Template string for prompts sent to the LLM for intent matching */
	UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Inworld|Intent",
		Meta = (ToolTip = "Template string for prompts sent to the LLM for intent matching"))
	FString PromptTemplate = "";

	/** Whether to use an embedding similarity threshold for filtering matches */
	UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Inworld|Intent",
		Meta = (ToolTip = "Whether to use an embedding similarity threshold for filtering matches"))
	bool bHasEmbeddingSimilarityThreshold{true};

	/** Minimum similarity threshold for embedding matches to be considered */
	UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Inworld|Intent",
		meta = (EditCondition = "bHasEmbeddingSimilarityThreshold", EditConditionHides,
			ToolTip = "Minimum similarity threshold for embedding matches to be considered"))
	float EmbeddingSimilarityThreshold = 0.7f;

	/** Whether to limit the number of embedding matches sent to the LLM */
	UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Inworld|Intent",
		Meta = (ToolTip = "Whether to limit the number of embedding matches sent to the LLM"))
	bool bHasMaxEmbeddingMatchesForLLM{true};

	/** Maximum number of embedding matches to send to the LLM for evaluation */
	UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Inworld|Intent",
		meta = (EditCondition = "bHasMaxEmbeddingMatchesForLLM", EditConditionHides,
			ToolTip = "Maximum number of embedding matches to send to the LLM for evaluation"))
	int MaxEmbeddingMatchesForLLM = 5;
};

/**
 * @struct FInworldIntentNodeCreationConfig
 * @brief Configuration for creating intent recognition nodes.
 *
 * This structure defines the creation-time parameters for intent nodes,
 * including the text embedder component to use for intent matching.
 */
USTRUCT(BlueprintType)
struct FInworldIntentNodeCreationConfig
{
	GENERATED_BODY()

	/** The ID of the text embedder component to use for intent matching */
	UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Inworld|Intent",
		meta = (GetOptions = "InworldRuntimeSettings.GetTextEmbedderIds",
			ToolTip = "The ID of the text embedder component to use for intent matching"))
	FString EmbedderComponentId{"Default"};
};

/**
 * @struct FInworldIntentNodeExecutionConfig
 * @brief Runtime configuration for intent recognition execution.
 *
 * This structure defines the runtime parameters for intent matching,
 * including the number of top matches to return and similarity thresholds.
 */
USTRUCT(BlueprintType)
struct FInworldIntentNodeExecutionConfig
{
	GENERATED_BODY()

	/** Maximum number of top intent matches to return */
	UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Inworld|Intent",
		Meta = (ToolTip = "Maximum number of top intent matches to return"))
	int TopNIntents = 1;

	/** Minimum similarity threshold for intent matches to be considered valid */
	UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Inworld|Intent",
		Meta = (ToolTip = "Minimum similarity threshold for intent matches to be considered valid"))
	float SimilarityThreshold = 0.88f;
};

/**
 * @struct FInworldIntentsData
 * @brief Container for intent data including embeddings and assets.
 *
 * This structure holds the intent data used for matching, including both
 * raw text embeddings and references to text embedding assets.
 */
USTRUCT(BlueprintType)
struct FInworldIntentsData
{
	GENERATED_BODY()

	/** Map of intent names to their corresponding text embeddings */
	TMap<FName, TSharedPtr<const TArray<struct FInworldTextEmbedding>>> TextEmbeddings;

	/** Map of intent names to their corresponding text embedding assets */
	UPROPERTY(BlueprintReadOnly, Category = "Intent",
		Meta = (ToolTip = "Map of intent names to their corresponding text embedding assets"))
	TMap<FName, const class UInworldTextEmbeddingAsset*> TextEmbeddingAssets;
};
