#pragma once

#include "CoreMinimal.h"
#include "WingHandler.h"
#include "WingFetcher.h"
#include "WingUtils.h"
#include "WingTypes.h"
#include "WingServer.h"
#include "WingActorComponent.h"
#include "Engine/Blueprint.h"
#include "Engine/SimpleConstructionScript.h"
#include "Engine/SCS_Node.h"
#include "Components/ActorComponent.h"
#include "Kismet2/BlueprintEditorUtils.h"
#include "ActorComponent_Add.generated.h"


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

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

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

	UPROPERTY(EditAnywhere, meta=(Description="Component class name (e.g. StaticMeshComponent, SceneComponent)"))
	FString Class;

	UPROPERTY(EditAnywhere, meta=(Description="Component name for the new component"))
	FString Component;

	UPROPERTY(EditAnywhere, meta=(Description="Name of the parent component to attach to"))
	FString Parent;

	virtual void Register() override
	{
		UWingServer::AddHandler(this,
			TEXT("Add a component to a Blueprint's SimpleConstructionScript. "
			"Optionally attach it to an existing parent component."));
	}
	virtual void Handle() override
	{
		WingFetcher F;
		UBlueprint* BP = F.Asset(Blueprint).Cast<UBlueprint>();
		if (!BP) return;

		// Check that the proposed name is valid
		FName InternalID = WingUtils::CheckProposedName(Component);
		if (InternalID.IsNone()) return;
		TSet<FName> Names;
		FBlueprintEditorUtils::GetClassVariableList(BP, Names);
		if (!WingUtils::FindNoDuplicateName(Names, InternalID, TEXT("variable or component"))) return;

		// Resolve the component class by name
		UWingTypes::Requirements Req;
		Req.BlueprintType = false;
		Req.Blueprintable = false;
		Req.AllowContainer = false;
		Req.IsChildOf = UActorComponent::StaticClass();
		UClass* ComponentClass = UWingTypes::TextToOneObjectType(Class, Req);
		if (!ComponentClass) return;
		if (!UWingComponentReference::CheckValidComponentClass(ComponentClass)) return;

		// Find the specified parent component
		TArray<UWingComponentReference*> AllComponents = UWingComponentReference::GetAll(BP);
		UWingComponentReference* ParentComp = WingUtils::FindOneWithExternalID(Parent, AllComponents, TEXT("Component"));
		if (!ParentComp) return;

		// Create the SCS node
		if (!UWingComponentReference::AddComponent(BP, ComponentClass, ParentComp, InternalID)) return;

		UWingServer::Printf(TEXT("Component Added.\n"));
	}
};
