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

#pragma once

#include "CoreMinimal.h"
#include "Graph/InworldGraphRuntimeData.h"
#include "Graph/Nodes/InworldNode_Intent.h"
#include "Primitives/Intent/InworldIntentTypes.h"

#include "InworldGraphRuntimeData_Intent.generated.h"

/**
 * @class UInworldGraphRuntimeData_Intent
 * @brief Runtime data class for managing intent recognition in Inworld graphs.
 *
 * This class compiles and stores all necessary data for intent matching operations,
 * including text embeddings for intent recognition, enable/disable states, and
 * asset management. It supports dynamic adding, removing, and toggling of intents
 * during graph execution.
 */
UCLASS(BlueprintType, meta = (DisplayName = "Intent Data"))
class INWORLDRUNTIME_API UInworldGraphRuntimeData_Intent : public UInworldGraphRuntimeData
{
	GENERATED_BODY()

public:
	/**
	 * @brief Default constructor for the intent runtime data.
	 */
	UInworldGraphRuntimeData_Intent();

	/**
	 * @brief Retrieves the intent data wrapped in an InworldDataHandle.
	 *
	 * This override implementation returns the current intent recognition data,
	 * making it accessible to intent nodes within the graph system.
	 *
	 * @return Handle containing the intent recognition data
	 */
	virtual FInworldDataHandle GetData() override;

	/**
	 * @brief Initializes the intent runtime data.
	 *
	 * This override implementation processes initial intent assets, loads their
	 * text embeddings, and prepares the intent recognition system for use during
	 * graph execution.
	 */
	virtual void Initialize_Implementation() override;

	/**
	 * @brief Sets the initial intent assets for the runtime data.
	 *
	 * This function configures the collection of intent assets that will be loaded
	 * and made available for intent recognition during graph execution.
	 *
	 * @param IntentAssets Map of intent identifiers to their corresponding text embedding assets
	 */
	UFUNCTION(BlueprintCallable, Category = "Inworld|Intent")
	void Set(const TMap<FName, UInworldTextEmbeddingAsset*>& IntentAssets);

	/**
	 * @brief Adds a new intent to the runtime data, with an option to replace an existing set.
	 * @param Id The unique identifier of the intent set to be added.
	 * @param Intent The intent to be added.
	 * @param Replace If true, replaces an existing intent with the same ID. Defaults to false.
	 */
	UFUNCTION(BlueprintCallable, Category = "Inworld|Intents")
	void AddIntentTextEmbeddingAsset(FName Id, const UInworldTextEmbeddingAsset* Intent, bool Replace = false);

	/**
	 * @brief Adds a new intent to the runtime data, with an option to replace an existing set.
	 * @param Id The unique identifier of the intent set to be added.
	 * @param Intent The intent to be added.
	 * @param Replace If true, replaces an existing intent with the same ID. Defaults to false.
	 */
	UFUNCTION(BlueprintCallable, Category = "Inworld|Intents")
	void AddIntentTextEmbeddings(FName Id, const TArray<FInworldTextEmbedding>& Intent, bool Replace = false);

	/**
	 * @brief Removes a specific intent identified by its unique ID.
	 * @param Id The unique identifier of the intent to be removed.
	 */
	UFUNCTION(BlueprintCallable, Category = "Inworld|Intent")
	void RemoveIntent(FName Id);

	/**
	 * @brief Enables a specific intent within the runtime data.
	 * @param Id The unique identifier for the intent to be enabled.
	 */
	UFUNCTION(BlueprintCallable, Category = "Inworld|Intent")
	void EnableIntent(FName Id);

	/**
	 * @brief Disables a specific intent within the runtime data.
	 * @param Id The unique identifier for the intent to be disabled.
	 */
	UFUNCTION(BlueprintCallable, Category = "Inworld|Intent")
	void DisableIntent(FName Id);

	/**
	 * @brief Retrieves all intent set IDs currently stored in the runtime data.
	 */
	UFUNCTION(BlueprintPure, Category = "Inworld|Intent")
	TArray<FName> GetIntentMapKeys() const;

protected:
	/** Initial intent assets loaded during initialization */
	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Intent Runtime Data",
		meta = (ToolTip = "Initial intent assets loaded during initialization"))
	TMap<FName, TObjectPtr<const UInworldTextEmbeddingAsset>> InitialIntents;

	/** Currently enabled intent embeddings available for recognition */
	TMap<FName, TSharedPtr<const TArray<FInworldTextEmbedding>>> EnabledIntents;

	/** Currently disabled intent embeddings (temporarily unavailable) */
	TMap<FName, TSharedPtr<const TArray<FInworldTextEmbedding>>> DisabledIntents;

	/** References to enabled intent assets for management */
	TMap<FName, const UInworldTextEmbeddingAsset*> EnabledIntentAssets;

	/** References to disabled intent assets for management */
	TMap<FName, const UInworldTextEmbeddingAsset*> DisabledIntentAssets;

	friend UInworldNode_Intent;
};
