#pragma once

#include "CoreMinimal.h"
#include "WingBasics.h"
#include "WingFetcher.h"
#include "WingUtils.h"
#include "WingTypes.h"
#include "WingServer.h"
#include "Engine/Blueprint.h"
#include "Kismet2/BlueprintEditorUtils.h"
#include "BlueprintInterface_Remove.generated.h"


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

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

public:
	UPROPERTY(EditAnywhere, meta=(Description="Blueprint name or package path"))
	FString Blueprint;

	UPROPERTY(EditAnywhere, meta=(Description="Interface name to remove"))
	FString Interface;

	UPROPERTY(EditAnywhere, meta=(Description="If true, keep the function graphs as regular functions"))
	bool PreserveFunctions = false;

	virtual void Register() override
	{
		UWingServer::AddHandler(this,
			TEXT("Remove a Blueprint Interface implementation from a Blueprint. "
			"Optionally preserve the function graphs as regular functions."));
	}
	virtual void Handle() override
	{
		WingFetcher F(WingOut::Stdout);
		UBlueprint* BP = F.Asset(Blueprint).Cast<UBlueprint>();
		if (!BP) return;

		// Resolve the interface name to a UClass*
		UWingTypes::Requirements Req;
		Req.AllowContainer = false;
		Req.IsChildOf = UInterface::StaticClass();
		FEdGraphPinType PinType;
		if (!UWingTypes::TextToType(Interface, PinType, Req, WingOut::Stdout)) return;
		UClass* FoundInterface = Cast<UClass>(PinType.PinSubCategoryObject.Get());
		check(FoundInterface);

		// Verify this blueprint actually implements it
		bool Found = false;
		for (const FBPInterfaceDescription& Desc : BP->ImplementedInterfaces)
		{
			if (Desc.Interface == FoundInterface) { Found = true; break; }
		}
		if (!Found)
		{
			WingOut::Stdout.Printf(TEXT("ERROR: Blueprint %s does not implement interface %s\n"),
				*WingUtils::FormatName(BP), *WingUtils::FormatName(FoundInterface));
			return;
		}

		FTopLevelAssetPath InterfacePath = FoundInterface->GetClassPathName();
		FBlueprintEditorUtils::RemoveInterface(BP, InterfacePath, PreserveFunctions);

		WingOut::Stdout.Printf(TEXT("Removed interface %s\n"), *WingUtils::FormatName(FoundInterface));
		if (PreserveFunctions)
			WingOut::Stdout.Print(TEXT("Function graphs preserved as regular functions.\n"));
	}
};
