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

#pragma once
#include "Graph/RuntimeData/InworldGraphRuntimeData_EmotionState.h"
#include "Graph/RuntimeData/InworldGraphRuntimeData_Goals.h"
#include "Graph/RuntimeData/InworldGraphRuntimeData_Intent.h"
#include "Graph/RuntimeData/InworldGraphRuntimeData_Knowledge.h"
#include "Graph/RuntimeData/InworldGraphRuntimeData_KnowledgeFilter.h"
#include "Graph/RuntimeData/InworldGraphRuntimeData_RelationState.h"
#include "InworldSimpleCharacterComponent.h"

#include "InworldCharacterComponent.generated.h"

// Forward declarations
class UInworldCharacterComponent;
class UInworldConversationGroup;
struct FInworldCharacterTrigger;
struct FInworldData_IndexedTTSOutput;
struct FInworldData_DataStream_TTSOutput;

/**
 * Delegate fired when a character goal is completed or achieved.
 * Provides the character component and the name of the completed goal.
 */
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(
	FOnInworldGoalComplete, const UInworldCharacterComponent*, CharacterComponent, FName, GoalName);

/** Native delegate fired when a character goal is completed */
DECLARE_MULTICAST_DELEGATE_TwoParams(
	FOnInworldGoalCompleteNative, const UInworldCharacterComponent* /*CharacterComponent*/, FName /*GoalName*/);

/**
 * Full-featured Inworld character component with advanced AI capabilities.
 *
 * This component represents the complete implementation of an Inworld AI character,
 * extending the simple character with advanced features like emotion tracking,
 * relationship states, dynamic knowledge systems, goal management, and trigger support.
 *
 * Advanced Features:
 * - Emotion state tracking and emotional responses
 * - Relationship state management with dynamic character relationships
 * - Knowledge base and knowledge filtering
 * - Goal system with completion tracking
 * - Intent recognition and processing
 * - Trigger system for scripted interactions
 *
 * This is the recommended component for complex AI characters requiring sophisticated
 * behavioral AI, emotional intelligence, and advanced conversation capabilities.
 */
UCLASS(ClassGroup = (Inworld), BlueprintType, Blueprintable, Meta = (BlueprintSpawnableComponent))
class INWORLDCHARACTER_API UInworldCharacterComponent : public UInworldSimpleCharacterComponent
{
	GENERATED_BODY()

public:
	/**
	 * @brief Checks if this character is currently part of a conversation group.
	 * @return True if the character is in a conversation group, false otherwise
	 */
	UFUNCTION(BlueprintCallable, Category = "Inworld")
	bool IsInConversationGroup()
	{
		return ConversationGroup != nullptr;
	}

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

	/**
	 * Gets all runtime data components for this advanced character.
	 * @return Array of all runtime data objects including advanced AI features
	 */
	virtual void GetRuntimeData(TMap<FName, FInworldDataHandle>& OutRuntimeData) const override;

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

protected:
	/**
	 * Called when the character's dialogue generation graph produces a result - handles advanced processing.
	 * @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;

	/**
	 * Updates the emotional state of the character based on the current response data.
	 *
	 * This method processes the character's current response, utilizing the emotion graph
	 * for advanced emotional state generation. If the current response is empty, an error
	 * is logged, and no updates are performed.
	 */
	void UpdateEmotionState();

	/**
	 * Updates the relationship state of the character based on the provided player profile.
	 * Allows dynamic adjustment of character relations during gameplay.
	 *
	 * @param PlayerProfile The profile data of the player used to update relationship state.
	 */
	void UpdateRelationState(const FInworldPlayerProfile& PlayerProfile);

	/**
	 * Updates the current conversation state for the character.
	 *
	 * Determines and sets the latest conversation state based on the character's
	 * conversation group, player interactions, and associated character profiles.
	 * If no conversation group exists, it initializes a default conversation state
	 * including basic participant information.
	 *
	 */
	void UpdateConversationState();

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

	/**
	 * Attempts to send the next message in the queue for processing.
	 * If the message queue is empty or there is already an active message being processed,
	 * the method exits without taking any action. Otherwise, it dequeues the next message,
	 * initiates its execution on the dialogue generation graph, and sets up callbacks
	 * for handling the result and monitoring execution status.
	 */
	virtual void TrySendNextMessage() override;

	/**
	 * Applies the data from an FInworldCharacterConfig struct to this component's properties, including advanced data.
	 * @param Data The character data to apply.
	 */
	virtual void ApplyCharacterData(const FInworldCharacterConfig& Data) override;

	virtual EInworldComponentType GetComponentType() const override;

public:
	/**
	 * Emotion state runtime data for tracking and managing character emotions.
	 * Controls emotional responses, mood changes, and emotional context in conversations.
	 */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Inworld|Manual Config",
		Meta = (DisplayPriority = "2", EditCondition = "!bUseDataTable",
			ToolTip =
				"Emotion state runtime data for tracking and managing character emotions. Controls emotional responses, mood changes, and emotional context in conversations"))
	TObjectPtr<UInworldGraphRuntimeData_EmotionState> EmotionState;

	/**
	 * Relationship state runtime data for managing character relationships.
	 * Tracks attraction, familiarity, respect, and trust with different characters.
	 */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Inworld|Manual Config",
		Meta = (DisplayPriority = "2", EditCondition = "!bUseDataTable",
			ToolTip =
				"Relationship state runtime data for managing character relationships. Tracks attraction, familiarity, respect, and trust with different characters"))
	TObjectPtr<UInworldGraphRuntimeData_RelationState> RelationState;

	/**
	 * Knowledge runtime data containing the character's knowledge base.
	 * Defines what the character knows and can reference in conversations.
	 */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Inworld|Manual Config",
		Meta = (DisplayPriority = "2", EditCondition = "!bUseDataTable",
			ToolTip =
				"Knowledge runtime data containing the character's knowledge base. Defines what the character knows and can reference in conversations"))
	TObjectPtr<UInworldGraphRuntimeData_Knowledge> Knowledge;

	/**
	 * Knowledge filter runtime data for controlling knowledge access.
	 * Filters what knowledge the character can use in different contexts.
	 */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Inworld|Manual Config",
		Meta = (DisplayPriority = "2", EditCondition = "!bUseDataTable",
			ToolTip =
				"Knowledge filter runtime data for controlling knowledge access. Filters what knowledge the character can use in different contexts"))
	TObjectPtr<UInworldGraphRuntimeData_KnowledgeFilter> KnowledgeFilter;

	/**
	 * Goals runtime data for managing character objectives and motivations.
	 * Defines what the character wants to achieve in conversations.
	 */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Inworld|Manual Config",
		Meta = (DisplayPriority = "2", EditCondition = "!bUseDataTable",
			ToolTip =
				"Goals runtime data for managing character objectives and motivations. Defines what the character wants to achieve in conversations"))
	TObjectPtr<UInworldGraphRuntimeData_Goals> Goals;

	/**
	 * Intent runtime data for recognizing and processing user intentions.
	 * Helps the character understand what the player wants to accomplish.
	 */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Inworld|Manual Config",
		Meta = (DisplayPriority = "2", EditCondition = "!bUseDataTable",
			ToolTip =
				"Intent runtime data for recognizing and processing user intentions. Helps the character understand what the player wants to accomplish"))
	TObjectPtr<UInworldGraphRuntimeData_Intent> Intents;

	/** Event fired when a character goal is completed */
	UPROPERTY(BlueprintAssignable, Category = "Inworld")
	FOnInworldGoalComplete OnGoalComplete;
	FOnInworldGoalCompleteNative OnGoalCompleteNative;

protected:
	/** Runtime data key for accessing conversation state information during message processing */
	UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Inworld|Key Name",
		Meta = (ToolTip = "Runtime data key for accessing conversation state information during message processing"))
	FName ConversationStateRuntimeDataKey{"ConversationState"};

	/**
	 * Conversation state runtime data tracking current dialogue context and flow.
	 * Automatically managed - contains the current state of active conversations.
	 */
	UPROPERTY(BlueprintReadOnly, Category = "Inworld",
		Meta = (ToolTip =
					"Conversation state runtime data tracking current dialogue context and flow. Automatically managed - contains the current state of active conversations"))
	FInworldConversationState ConversationState;

	/** Graph asset for generating the character's emotional state based on dialogue */
	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Inworld|Graph",
		Meta = (ToolTip = "Graph asset for generating the character's emotional state based on dialogue"))
	TObjectPtr<UInworldGraphAsset> EmotionGraphAsset;

	/** Runtime instance of the emotion graph for emotional state generation */
	UPROPERTY(BlueprintReadOnly, Category = "Inworld|Graph",
		Meta = (ToolTip = "Runtime instance of the emotion graph for emotional state generation"))
	TObjectPtr<UInworldGraph> EmotionGraph;

	/** Graph asset for managing the character's relationship dynamics with the player */
	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Inworld|Graph",
		Meta = (ToolTip = "Graph asset for managing the character's relationship dynamics with the player"))
	TObjectPtr<UInworldGraphAsset> RelationGraphAsset;

	/** Runtime instance of the relationship graph for relationship state updates */
	UPROPERTY(BlueprintReadOnly, Category = "Inworld|Graph",
		Meta = (ToolTip = "Runtime instance of the relationship graph for relationship state updates"))
	TObjectPtr<UInworldGraph> RelationGraph;

	/** Reference to the conversation group this character belongs to, if any */
	UPROPERTY(BlueprintReadOnly, Category = "Inworld",
		Meta = (ToolTip = "Reference to the conversation group this character belongs to, if any"))
	TObjectPtr<UInworldConversationGroup> ConversationGroup;

	friend UInworldConversationGroup;
};
