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

#pragma once
#include "Graph/RuntimeData/InworldGraphRuntimeData_CharacterProfile.h"
#include "Graph/RuntimeData/InworldGraphRuntimeData_EventHistory.h"
#include "Graph/RuntimeData/InworldGraphRuntimeData_Memory.h"
#include "Graph/RuntimeData/InworldGraphRuntimeData_Voice.h"
#include "InworldBaseCharacterComponent.h"

#include "InworldSimpleCharacterComponent.generated.h"

/**
 * Delegate fired when character dialogue is generated and ready.
 * Provides the character component, message identifier, and complete response data.
 */
DECLARE_DYNAMIC_MULTICAST_DELEGATE_ThreeParams(FOnInworldCharacterDialogueResponse, UInworldSimpleCharacterComponent*,
	CharacterComponent, const FString&, MessageId, const FInworldCharacterResponse&, Response);

/** Native delegate fired when character dialogue is generated */
DECLARE_MULTICAST_DELEGATE_ThreeParams(FOnInworldCharacterDialogueResponseNative,
	UInworldSimpleCharacterComponent* /*CharacterComponent*/, const FString& /*MessageId*/,
	const FInworldCharacterResponse& /*Response*/);

/**
 * Simple implementation of Inworld character component with essential runtime data.
 *
 * This component extends the base character functionality by adding core runtime data
 * management including character profile, voice settings, event history, and conversation
 * state. It provides a ready-to-use character implementation with fundamental AI features.
 *
 * Key Features:
 * - Character profile and personality configuration
 * - Voice and speech settings
 * - Event history tracking for context
 * - Conversation state management
 * - Spawnable in Blueprint editor
 * - Complete basic character functionality
 *
 * This serves as the foundation for more advanced character implementations while providing
 * all essential features for basic AI character interactions.
 */
UCLASS(ClassGroup = (Inworld), BlueprintType, Blueprintable, Meta = (BlueprintSpawnableComponent))
class INWORLDCHARACTER_API UInworldSimpleCharacterComponent : public UInworldBaseCharacterComponent
{
	GENERATED_BODY()

public:
	/**
	 * Updates the event history by adding a new speech event entry.
	 *
	 * This method allows the character's event history to be updated with a new
	 * speech event. The event is captured and stored in the runtime data's event
	 * history, providing context for future interactions.
	 *
	 * @param EventHistoryEntry The speech event entry to be added to the event history.
	 */
	UFUNCTION(BlueprintCallable, Category = "Inworld|Event History")
	void AddHistoryEvent(const FInworldEventSpeech& EventHistoryEntry);

	/**
	 * Clears the character's event history data, resetting all stored interactions.
	 *
	 * This method ensures that the event history runtime data is wiped clean,
	 * removing all previously recorded conversation or event entries. It logs an
	 * error message if the event history data is null or invalid.
	 */
	UFUNCTION(BlueprintCallable, Category = "Inworld|Event History")
	void ClearHistory() const;

protected:
	/** Called when the component begins play - initializes runtime data */
	virtual void BeginPlay() override;

	/**
	 * Cancels the current message, clears the message queue, and stops the character's speech.
	 */
	virtual void Interrupt_Implementation() override;

	/**
	 * Called when the character's AI dialogue generation graph produces a result.
	 * @param ExecutionId The unique identifier for the graph execution
	 * @param DataHandle Handle to the result data
	 */
	virtual void OnDialogueGenerationResult_Implementation(
		const FString& ExecutionId, const FString& NodeId, const FInworldDataHandle& DataHandle) override;

	/**
	 * Called when the dialogue generation status of a graph execution is updated.
	 *
	 * This method is triggered to notify about the current state of a graph execution,
	 * providing detailed updates about its progress or final result.
	 *
	 * @param ExecutionId The unique identifier for the graph execution.
	 * @param Status The current execution status of the graph, such as Pending, Running, Completed, Canceled, or Failed.
	 */
	virtual void OnDialogueGenerationStatus_Implementation(
		const FString& ExecutionId, EInworldGraphExecutionStatus Status) override;

	/**
	 * Gets all runtime data components for this character.
	 * @return Map of runtime data used by this character
	 */
	virtual void GetRuntimeData(TMap<FName, FInworldDataHandle>& OutRuntimeData) const override;

	/**
	 * Clears the current response data for the character.
	 *
	 * This method resets the current response by clearing its query and result content.
	 * It is typically used to reset the dialogue state for generating new interactions
	 * or responses during runtime. Ensures the character is ready for a fresh response cycle.
	 */
	void ClearCurrentResponse();

	/**
	 * Attempts to signal that the component is ready, provided that necessary graphs are initialized.
	 */
	virtual void TrySignalReady() override;

	/**
	 * Gets all runtime data and its associated type for this character.
	 * @return Array of FRuntimeDataInfo structures.
	 */
	virtual TArray<FRuntimeDataInfo> GetRuntimeDataAndType() const override;

	/**
	 * Applies the data from an FInworldCharacterConfig struct to this component's properties.
	 * This is called by BeginPlay if bUseDataTable is true.
	 * @param Data The character data to apply.
	 */
	virtual void ApplyCharacterData(const FInworldCharacterConfig& Data) override;

	virtual EInworldComponentType GetComponentType() const override;

public:
	/**
	 * Character profile runtime data containing personality, backstory, and behavior settings.
	 * This defines who the character is and how they should behave in conversations.
	 */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Inworld|Manual Config",
		Meta = (DisplayPriority = "1", EditCondition = "!bUseDataTable",
			ToolTip =
				"Character profile runtime data containing personality, backstory, and behavior settings. This defines who the character is and how they should behave in conversations"))
	TObjectPtr<UInworldGraphRuntimeData_CharacterProfile> CharacterProfile;

	/**
	 * Voice runtime data containing speech settings, language, and voice characteristics.
	 * Controls how the character's speech is synthesized and played back.
	 */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Inworld|Manual Config",
		Meta = (DisplayPriority = "1", EditCondition = "!bUseDataTable",
			ToolTip =
				"Voice runtime data containing speech settings, language, and voice characteristics. Controls how the character's speech is synthesized and played back"))
	TObjectPtr<UInworldGraphRuntimeData_Voice> Voice;

	/**
	 * Event history runtime data for tracking conversation context and past interactions.
	 * Enables the character to remember and reference previous conversations.
	 */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Inworld|Manual Config",
		Meta = (DisplayPriority = "1", EditCondition = "!bUseDataTable",
			ToolTip =
				"Event history runtime data for tracking conversation context and past interactions. Enables the character to remember and reference previous conversations"))
	TObjectPtr<UInworldGraphRuntimeData_EventHistory> EventHistory;

	/** Long-term conversation history */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Inworld|Manual Config",
		Meta = (DisplayPriority = "1", EditCondition = "!bUseDataTable",
			ToolTip = "Memory runtime data for summarizing long conversation histories"))
	TObjectPtr<UInworldGraphRuntimeData_Memory> Memory;

	/** Event fired when dialogue is generated */
	UPROPERTY(BlueprintAssignable, Category = "Inworld")
	FOnInworldCharacterDialogueResponse OnDialogueResponse;
	FOnInworldCharacterDialogueResponseNative OnDialogueResponseNative;

protected:
	/** Current response data being processed by the character */
	FInworldCharacterResponse CurrentResponse;

private:
	/** Counter for tracking TTS response generation */
	int32 TTSResponseCount;
};
