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

#pragma once
#include "InworldTextEmbeddingsFactory.h"
#include "Primitives/TextEmbedder/InworldTextEmbedding.h"
#include "Tools/InworldTextEmbedder.h"

#include "InworldEditorTextEmbedder.generated.h"

namespace inworld
{
class TextEmbedderInterface;
}

DECLARE_DYNAMIC_DELEGATE_TwoParams(FOnTextArrayStringParsed, bool, bSuccess, const TArray<FString>&, TextArray);

/**
 * @brief Provides functionality to embed text as embeddings using Inworld AI's Text Embedding services.
 * Offers static and asynchronous methods for embedding single or multiple text inputs.
 * Supports asset creation to store embeddings and methods to handle embedding results.
 *
 * @note The text array string input format takes the form of a list of text records (strings) separated by commas.
 * Commas are used as separators to distinguish between different text records.
 * Text records can be enclosed in various styles of quotes (e.g., "text", 'text', “text”).
 * If enclosed in quotes, commas within the quotes are not treated as separators.
 * The entire input can optionally be enclosed in parentheses.
 *
 * Example valid text array string inputs:
 * - Without quotes or parentheses:     Text1,Text2,Text3
 * - With neutral double quotes:		"Text1","Text2, Part2","Text3"
 * - With neutral single quotes:		'Text1','Text2'
 * - With styled quotes:				(“Text1”, ‘Text2’)
 * - With parentheses:					(Text1,Text2,Text3) or ("Text1","Text2")
 * - Mixed and matched:					(Text1, "Text2", ‘Text3’, “Text4, Part4”)
 *
 */
UCLASS(BlueprintType)
class INWORLDRUNTIMEEDITOR_API UInworldEditorTextEmbedder : public UObject
{
	GENERATED_BODY()

public:
	/**
	 * @brief Creates an instance of UInworldEditorTextEmbedder with the given configuration ID.
	 * @param ConfigId Identifier for the configuration to use for creating the text embedder.
	 * @return A pointer to the instance of UInworldEditorTextEmbedder.
	 */
	UFUNCTION(BlueprintCallable, Category = "Inworld|Text Embedder")
	static UInworldEditorTextEmbedder* CreateInworldEditorTextEmbedder(const FString& ConfigId);

	/**
	 * @brief Asynchronously embeds a batch of text inputs and saves them to a new data asset.
	 * @param Text Array of text strings to be embedded asynchronously.
	 */
	UFUNCTION(BlueprintCallable, Category = "Inworld|Text Embedder")
	void EmbedAsync(const TArray<FString>& Text);

	/**
	 * @brief Parses a string representing an array of text records into a TArray of FString.
	 * This function flexibly handles various quotation mark styles for enclosing text entries.
	 * It supports neutral double quotes (" "), neutral single quotes (' '), and styled quotes (“ ” ‘ ’).
	 * Unquoted entries and optional surrounding parentheses are also supported.
	 *
	 * @param TextArrayString A string representing the text array. See the class documentation for more examples.
	 * @param Callback The callback function for returning the individual text records parsed from the input string.
	 *
	 */
	UFUNCTION(BlueprintCallable, Category = "Inworld|Text Embedder")
	static void ParseTextArrayString(const FString& TextArrayString, FOnTextArrayStringParsed Callback);

private:
	/**
	 * @brief Creates a text embedding asset for storing the resulting embeddings.
	 * @return A pointer to the created UInworldTextEmbeddingAsset instance.
	 */
	UInworldTextEmbeddingAsset* CreateTextEmbeddingsAsset() const;

	/**
	 * @brief Callback function triggered when text embedding is completed.
	 * @param bSuccess Indicates whether the embedding operation succeeded.
	 * @param TextEmbeddings The resulting embeddings from the operation.
	 */
	void OnTextEmbedded(bool bSuccess, const TArray<FInworldTextEmbedding>& TextEmbeddings) const;

private:
	UPROPERTY()
	TObjectPtr<UInworldTextEmbedder> TextEmbedder;

	UPROPERTY()
	TObjectPtr<UInworldTextEmbeddingsFactory> TextEmbeddingsFactory;

	UPROPERTY()
	FString CachedConfigId;
};
