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

#pragma once

#include "CoreMinimal.h"
#include "Graph/InworldNode.h"
#include "InworldNode_Custom.h"
#include "Primitives/TTS/InworldTTSTypes.h"

#include "InworldNode_TTS.generated.h"

/**
 * @class UInworldNode_TTS
 * @brief A node that converts text input to synthesized speech using
 * Text-to-Speech.
 *
 * This node takes either a single text input or a stream of text inputs and
 * converts them to a stream of TTSOutput objects containing both the original
 * text and the synthesized audio. It inherits from TypedNode with specific
 * input/output types for handling text and audio data.
 *
 * @input FInworldData_Text OR FInworldData_DataStream_String (Text data to convert to speech)
 * @input FInworldData_Text (Optional emotion text to influence speech synthesis)
 * @output FInworldData_DataStream_TTSOutput
 */
UCLASS()
class INWORLDRUNTIME_API UInworldNode_TTS : public UInworldNode
{
	GENERATED_BODY()

public:
	UInworldNode_TTS();

	/**
	 * @brief Creates a new native UInworldNode_TTS instance with the specified parameters.
	 * @param Outer The outer UObject that will own this node instance
	 * @param NodeName The name to assign to the created node
	 * @param ExecutionConfig The TTS node configuration settings
	 * @return A pointer to the newly created UInworldNode_TTS instance, or nullptr if creation fails
	 */
	static UInworldNode_TTS* CreateNative(
		class UObject* Outer, const FString& NodeName, const FInworldTTSNodeExecutionConfig& ExecutionConfig);

	/** Configuration settings for TTS node execution including component ID and voice settings */
	UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = "Inworld",
		Meta = (ToolTip = "Configuration settings for TTS node execution including component ID and voice settings"))
	FInworldTTSNodeExecutionConfig ExecutionConfig{};

private:
	virtual EInworldRuntimeErrors GetJsonConfig(const TSharedRef<FJsonObject>& GraphJson) override;

	UFUNCTION()
	UPARAM(meta = (DisplayName = "TTS Output"))
	FInworldData_DataStream_TTSOutput Process_Text(const FInworldData_Text& Text)
	{
		checkNoEntry();
		return {};
	}

	UFUNCTION()
	UPARAM(meta = (DisplayName = "TTS Output"))
	FInworldData_DataStream_TTSOutput Process_TextStream(const FInworldData_DataStream_String& TextStream)
	{
		checkNoEntry();
		return {};
	}

	UFUNCTION()
	UPARAM(meta = (DisplayName = "TTS Output"))
	FInworldData_DataStream_TTSOutput Process_TTSRequest(const FInworldData_TTSRequest& TTSRequest)
	{
		checkNoEntry();
		return {};
	}
};

/**
 * @class UInworldNode_TTSRequest
 * @brief A node that creates a TTSRequest for the TTS node.
 *
 *	Fetches Voice configuration from any available Voice runtime data.
 *
 * @input FInworldData_DataStream_String
 * @output FInworldData_TTSRequest
 */
UCLASS()
class INWORLDRUNTIME_API UInworldNode_TTSRequest : public UInworldNode_Custom
{
	GENERATED_BODY()

public:
	/**
	 * @brief Default constructor for the TTS request node.
	 *
	 * Initializes the node with default settings for creating TTS requests
	 * from text input and voice configuration.
	 */
	UInworldNode_TTSRequest();

protected:
	/**
	 * @brief Creates a TTS request from text stream input and voice configuration.
	 *
	 * This function combines streaming text data with voice settings to create a TTS request
	 * suitable for speech synthesis. It fetches voice configuration from available runtime data
	 * and packages it with the text stream for processing by TTS nodes.
	 *
	 * @param ProcessContext Runtime context containing execution state and voice runtime data
	 * @param TextStream The input text stream to be converted to speech
	 * @param Voice Voice configuration settings for speech synthesis
	 * @return TTS request containing text stream and voice configuration
	 */
	UFUNCTION()
	virtual UPARAM(meta = (DisplayName = "TTS Request")) FInworldData_TTSRequest
		Process_DataStream_String(const UInworldProcessContext* ProcessContext, const FInworldData_DataStream_String& TextStream,
			const FInworldVoice& Voice) const;

	/**
	 * @brief Creates a TTS request from single text input and voice configuration.
	 *
	 * This function combines simple text data with voice settings to create a TTS request
	 * suitable for speech synthesis. It fetches voice configuration from available runtime data
	 * and packages it with the text input for processing by TTS nodes.
	 *
	 * @param ProcessContext Runtime context containing execution state and voice runtime data
	 * @param Text The input text to be converted to speech
	 * @param Voice Voice configuration settings for speech synthesis
	 * @return TTS request containing text and voice configuration
	 */
	UFUNCTION()
	virtual UPARAM(meta = (DisplayName = "TTS Request")) FInworldData_TTSRequest
		Process_Text(const UInworldProcessContext* ProcessContext, const FInworldData_Text& Text, const FInworldVoice& Voice) const;
};
