#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 "Kismet2/KismetEditorUtilities.h"
#include "Blueprint_Reparent.generated.h"


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

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

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

	UPROPERTY(EditAnywhere, meta=(Description="New parent class"))
	FString Parent;

	virtual void Register() override
	{
		UWingServer::AddHandler(this,
			TEXT("Change a Blueprint's parent class."));
	}
	virtual void Handle() override
	{
		// Load Blueprint
		WingFetcher F(WingOut::Stdout);
		UBlueprint* BP = F.Asset(Blueprint).Cast<UBlueprint>();
		if (!BP) return;

		// Find the new parent class by short type name
		UWingTypes::Requirements Req;
		Req.Blueprintable = true;
		Req.AllowContainer = false;
		Req.IsChildOf = UObject::StaticClass();
		FEdGraphPinType PinType;
		if (!UWingTypes::TextToType(Parent, PinType, Req, WingOut::Stdout)) return;
		UClass* NewParentClassObj = Cast<UClass>(PinType.PinSubCategoryObject.Get());
		check(NewParentClassObj);
		
		// Validate reparent
		if (!WingUtils::CanReparentBlueprint(BP->GeneratedClass, NewParentClassObj))
		{
			WingOut::Stdout.Printf(TEXT("Error: Cannot reparent %s to %s — incompatible class hierarchy.\n"),
				*WingUtils::FormatName(BP), *WingUtils::FormatName(NewParentClassObj));
			return;
		}

		// Perform reparent
		BP->ParentClass = NewParentClassObj;
		FBlueprintEditorUtils::RefreshAllNodes(BP);
		FKismetEditorUtilities::CompileBlueprint(BP);

		WingOut::Stdout.Printf(TEXT("Reparented %s -> %s\n"),
			*WingUtils::FormatName(BP), *WingUtils::FormatName(NewParentClassObj));
	}
};
