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

#pragma once

#include "CoreMinimal.h"
#include "Graph/InworldCharacterData.h"
#include "Graph/Nodes/InworldNode_Custom.h"
#include "Graph/RuntimeData/InworldGraphRuntimeData_Goals.h"
#include "InworldCharacterTypes.h"

#include "InworldNode_Goals.generated.h"

/**
 * @class UInworldNode_Goals
 * @brief Node that processes and advances character goals based on intents or explicit triggers.
 *
 * This node matches incoming intents or triggers against the character's configured goals
 * and produces corresponding actions to advance the goal system. It supports both
 * text-triggered goals (via intent matching) and explicit goal triggers with parameters.
 * The node resolves goal parameters dynamically from runtime data and registered parameter sources.
 *
 * @input FInworldData_MatchedIntents OR FInworldCharacterTrigger OR FInworldCharacterAction
 * @output FInworldCharacterAction
 */
UCLASS()
class INWORLDCHARACTER_API UInworldNode_Goals : public UInworldNode_Custom
{
	GENERATED_BODY()

public:
	/**
	 * @brief Default constructor for the goals node.
	 */
	UInworldNode_Goals();

	/** Runtime data key for accessing character profile information for goal processing */
	UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Inworld|Key Name",
		Meta = (ToolTip = "Runtime data key for accessing character profile information for goal processing"))
	FName CharacterProfileRuntimeDataKey{"CharacterProfile"};

	/** Runtime data key for accessing player profile information for goal parameter resolution */
	UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Inworld|Key Name",
		Meta = (ToolTip = "Runtime data key for accessing player profile information for goal parameter resolution"))
	FName PlayerProfileRuntimeDataKey{"PlayerProfile"};

private:
	/**
	 * @brief Processes an existing action through the goal system (pass-through).
	 * @param Action The action to process
	 * @param Goals The goals data for validation/context
	 * @return The same action, potentially validated or modified
	 */
	UFUNCTION()
	virtual UPARAM(meta = (DisplayName = "Action")) FInworldCharacterAction
		Process_Action(const FInworldCharacterAction& Action, const FInworldGoalsData& Goals) const;

	/**
	 * @brief Processes matched intents to find and trigger corresponding goals.
	 * @param ProcessContext The process context containing runtime data
	 * @param MatchedIntents The matched intents from intent recognition
	 * @param Goals The goals data containing goal definitions
	 * @return The action to execute for the matched goal, or empty action if no match
	 */
	UFUNCTION()
	virtual UPARAM(meta = (DisplayName = "Action")) FInworldCharacterAction
		Process_MatchedIntents(const UInworldProcessContext* ProcessContext, const FInworldData_MatchedIntents& MatchedIntents,
			const FInworldGoalsData& Goals) const;

	/**
	 * @brief Processes an explicit goal trigger to produce the corresponding action.
	 * @param ProcessContext The process context containing runtime data
	 * @param Trigger The goal trigger containing goal name and parameters
	 * @param Goals The goals data containing goal definitions
	 * @return The action to execute for the triggered goal
	 */
	UFUNCTION()
	virtual UPARAM(meta = (DisplayName = "Action")) FInworldCharacterAction
		Process_Trigger(const UInworldProcessContext* ProcessContext, const FInworldCharacterTrigger& Trigger,
			const FInworldGoalsData& Goals) const;

	/**
	 * @brief Formats an action string by substituting parameter placeholders with actual values.
	 * @param Action The action string containing parameter placeholders like {paramName}
	 * @param Parameters Map of parameter names to values for substitution
	 * @return The formatted action string with all parameters resolved
	 */
	static FString FormatParameters(FString Action, const TMap<FString, FString>& Parameters);

	/**
	 * @brief Creates an action data structure from a goal and resolved parameters.
	 * @param GoalName The name of the goal being activated
	 * @param Goal The goal definition containing response configuration
	 * @param Parameters The resolved parameters for the goal action
	 * @return The complete action data structure ready for execution
	 */
	FInworldCharacterAction CreateActionData(
		FName GoalName, const FInworldGoal& Goal, const TMap<FString, FString>& Parameters) const;
};
