#pragma once

#include "CoreMinimal.h"
#include "WingBasics.h"
#include "WingFetcher.h"
#include "WingUtils.h"
#include "WingServer.h"
#include "EdGraph/EdGraph.h"
#include "EdGraph/EdGraphNode.h"
#include "MaterialGraph/MaterialGraphNode.h"
#include "Materials/Material.h"
#include "IMaterialEditor.h"
#include "GraphNode_Remove.generated.h"


// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------

UCLASS()
class UWing_GraphNode_Remove : public UWingHandler
{
	GENERATED_BODY()

public:
	UPROPERTY(EditAnywhere, meta=(Description="Node to delete"))
	FString NodePath;

	virtual void Register() override
	{
		UWingServer::AddHandler(this,
			TEXT("Delete a node from a graph. "
			"Cannot delete undeletable nodes (entry points, root nodes, etc)."));
	}
	virtual void Handle() override
	{
		WingFetcher F(WingOut::Stdout);
		UEdGraphNode* FoundNode = F.Walk(NodePath).Cast<UEdGraphNode>();
		if (!FoundNode) return;

		UEdGraph* Graph = FoundNode->GetGraph();
		FString NodeTitle = WingUtils::FormatName(FoundNode);
		FString GraphName = WingUtils::FormatName(Graph);

		if (!FoundNode->CanUserDeleteNode())
		{
			WingOut::Stdout.Printf(TEXT("ERROR: Cannot delete node '%s' in graph '%s' — it is not deletable.\n"),
				*NodeTitle, *GraphName);
			return;
		}

		if (Cast<UMaterialGraphNode>(FoundNode))
		{
			// Use the material editor's DeleteNodes to properly remove
			// both the graph node and the underlying material expression.
			UMaterial* Material = F.CastAsset<UMaterial>();
			if (!Material) return;

			IAssetEditorInstance* Editor = WingUtils::CheckOpenEditorForAsset(Material, WingOut::Stdout);
			if (!Editor) return;

			IMaterialEditor* MatEditor = static_cast<IMaterialEditor*>(Editor);
			MatEditor->DeleteNodes({FoundNode});
		}
		else
		{
			FoundNode->BreakAllNodeLinks();
			Graph->RemoveNode(FoundNode);
		}

		WingOut::Stdout.Printf(TEXT("Deleted node '%s' from graph '%s'.\n"), *NodeTitle, *GraphName);
	}
};
