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

#include "CoreMinimal.h"
#include "EdGraph/EdGraphNode.h"
#include "Graph/Assets/InworldNodeAsset.h"
#include "GraphEditor/InworldGraphNodeInputOutputSlot.h"
#include "EdNode_InworldGraphNode.generated.h"

class UEdNode_InworldGraphEdge;
class UEdGraph_InworldGraph;
class SEdNode_InworldGraphNode;

UCLASS(MinimalAPI)
class UInworldPinType : public UObject
{
	GENERATED_BODY()

public:
	UPROPERTY()
	TArray<TObjectPtr<UScriptStruct>> AllowedTypes;
	UPROPERTY()
	bool bOptional{false};
};


UCLASS(MinimalAPI)
class UEdNode_InworldGraphNode : public UEdGraphNode
{
	GENERATED_BODY()

public:
	UEdNode_InworldGraphNode();
	virtual ~UEdNode_InworldGraphNode();

	UPROPERTY(VisibleAnywhere, Instanced, Category = "Inworld Graph")
	TObjectPtr<UInworldNodeAsset> InworldGraphNode;

	UPROPERTY()
	TArray<FInworldNodeInputOutputSlot> CachedInputSlots;

	UPROPERTY()
	FInworldNodeInputOutputSlot CachedOutputSlot;

	UPROPERTY()
	bool bCachedSlotsInitialized{false};

	void SetInworldGraphNode(UInworldNodeAsset* InNode);
	UInworldGraphAsset* GetInworldGraph() const;

	SEdNode_InworldGraphNode* SEdNode;

	virtual void AllocateDefaultPins() override;
	virtual FText GetNodeTitle(ENodeTitleType::Type TitleType) const override;
	virtual void PrepareForCopying() override;
	virtual void AutowireNewNode(UEdGraphPin* FromPin) override;

	virtual UEdGraphPin* GetInputPin(int PinIndex = 1) const;
	virtual UEdGraphPin* GetOutputPin() const;
	
	virtual bool CanJumpToDefinition() const override;
	virtual void JumpToDefinition() const override;

	void CreateRuntimeNode(UInworldGraphAsset* SubGraphAsset);
	bool IsLeafNode() const;
	bool IsRootNode() const;

	void SetNodeAs(EInworldNodeType InNodeType);

	// Ensure UEdGraph pins count matches CachedInputSlots (add missing input pins only; keep links)
	void ForceSyncPinsFromCachedSlots();

#if WITH_EDITOR
	virtual void PostEditUndo() override;
#endif
};
