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

#include "K2Node_InworldGetRuntimeStruct.h"

#include "BlueprintActionDatabaseRegistrar.h"
#include "BlueprintNodeSpawner.h"
#include "InworldBlueprintFunctionLibrary.h"

void UK2Node_InworldGetRuntimeStruct::GetMenuActions(FBlueprintActionDatabaseRegistrar& ActionRegistrar) const
{
	Super::GetMenuActions(ActionRegistrar);
	UClass* Action = GetClass();
	if (ActionRegistrar.IsOpenForRegistration(Action))
	{
		auto CustomizeLambda = [](UEdGraphNode* NewNode, bool bIsTemplateNode, const FName FunctionName)
		{
			UK2Node_InworldGetRuntimeStruct* Node = CastChecked<UK2Node_InworldGetRuntimeStruct>(NewNode);
			UFunction* Function = UInworldBlueprintFunctionLibrary::StaticClass()->FindFunctionByName(FunctionName);
			check(Function);
			Node->SetFromFunction(Function);
		};

		UBlueprintNodeSpawner* GetNodeSpawner = UBlueprintNodeSpawner::Create(GetClass());
		check(GetNodeSpawner != nullptr);
		GetNodeSpawner->CustomizeNodeDelegate = UBlueprintNodeSpawner::FCustomizeNodeDelegate::CreateStatic(
			CustomizeLambda, GET_FUNCTION_NAME_CHECKED(UInworldBlueprintFunctionLibrary, GetRuntimeStruct));
		ActionRegistrar.AddBlueprintAction(Action, GetNodeSpawner);
	}
}

void UK2Node_InworldGetRuntimeStruct::PinDefaultValueChanged(UEdGraphPin* ChangedPin)
{
	Super::PinDefaultValueChanged(ChangedPin);
	if (ChangedPin->PinName == "ScriptStruct")
	{
		if (ChangedPin->LinkedTo.Num() == 0)
		{
			RefreshOutputStructType();
		}
	}
}

void UK2Node_InworldGetRuntimeStruct::PostReconstructNode()
{
	Super::PostReconstructNode();
	RefreshOutputStructType();
}

void UK2Node_InworldGetRuntimeStruct::ClearCachedBlueprintData(UBlueprint* Blueprint)
{
	Super::ClearCachedBlueprintData(Blueprint);
	RefreshOutputStructType();
}

void UK2Node_InworldGetRuntimeStruct::RefreshOutputStructType()
{
	UEdGraphPin* ValuePin = FindPinChecked(FName{"Struct"});
	UEdGraphPin* StructTypePin = FindPinChecked(FName{"ScriptStruct"});

	if (StructTypePin->DefaultObject != ValuePin->PinType.PinSubCategoryObject)
	{
		if (ValuePin->SubPins.Num() > 0)
		{
			GetSchema()->RecombinePin(ValuePin);
		}
		ValuePin->PinType.PinSubCategoryObject = StructTypePin->DefaultObject;
		ValuePin->PinType.PinCategory =
			(StructTypePin->DefaultObject == nullptr) ? UEdGraphSchema_K2::PC_Wildcard : UEdGraphSchema_K2::PC_Struct;
	}
}
