#pragma once

#include "CoreMinimal.h"
#include "Framework/Commands/UIAction.h"

struct FToolMenuEntry;
struct FToolMenuContext;
class UEdGraphNode;
class UEdGraphPin;
class UGraphNodeContextMenuContext;

// Utilities for manipulating UToolMenu structures.
// Uses WingHacks for private member access.
class WingToolMenu
{
public:
	// Get the menu items for a given Node.  This includes
	// the menu items for the pins.  The labels are updated to be
	// nice labels for an LLM.  Only includes action-based entries;
	// command-based entries (which depend on editor selection/focus
	// state) are excluded.
	static TArray<FToolMenuEntry> GetMenuItems(UEdGraphNode *Node, const FToolMenuContext &TMContext);

	// Resolve a menu entry to an executable action and check if it can execute.
	// Entries that use Command-based callbacks are always false.
	static bool CanExecute(const FToolMenuEntry& Entry, const FToolMenuContext& TMContext);

	// Resolve a menu entry to an executable action and execute it.
	// Returns false if the action is not active or has no bound delegate.
	// Entries that use Command-based callbacks are always false.
	static bool Execute(const FToolMenuEntry& Entry, const FToolMenuContext& TMContext);


private:
	// Add a synthetic menu entry. Calls CanExec immediately; if false,
	// the entry is not added. Both lambdas are stored in the FUIAction.
	static void AddEntry(TArray<FToolMenuEntry>& Entries, UEdGraphPin* Pin,
		const TCHAR* Label, FCanExecuteAction CanExec, FExecuteAction Exec);

	template<typename FC, typename FE>
	static void AddEntry(TArray<FToolMenuEntry>& Entries, UEdGraphPin* Pin,
		const TCHAR* Label, FC&& CanExec, FE&& Exec)
	{
		AddEntry(Entries, Pin, Label,
			FCanExecuteAction::CreateLambda(Forward<FC>(CanExec)),
			FExecuteAction::CreateLambda(Forward<FE>(Exec)));
	}

	static void AddSyntheticEntries(TArray<FToolMenuEntry> &Entries, UEdGraphNode *Node);
	static FText MakeBetterLabel(const UEdGraphPin *Pin, const FText &EntryLabel);
	static bool ContainsText(const TArray<FText> &Texts, const FText &Value);
	static TArray<FToolMenuEntry> GetMenuItems(
		UGraphNodeContextMenuContext *GNC, const FToolMenuContext &TMC);
};
