#pragma once

#include "CoreMinimal.h"
#include "Components/ActorComponent.h"
#include "ECustomizationCategory.h"
#include "CosmeticPieceMeshLoadingData.h"
#include "CustomizedSkeletalMesh.generated.h"

class USkinnedMeshComponent;
class USkeletalMeshComponent;
class AItemVfx;
class UCustomizedSkeletalMesh;

UCLASS(Blueprintable, meta=(BlueprintSpawnableComponent))
class DEADBYDAYLIGHT_API UCustomizedSkeletalMesh : public UActorComponent
{
	GENERATED_BODY()

public:
	DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FOnMeshSwitchEventBP, ECustomizationCategory, category, USkeletalMeshComponent*, mesh);

	DECLARE_DYNAMIC_MULTICAST_DELEGATE(FOnCustomizationReadyBP);

public:
	UPROPERTY(BlueprintReadWrite, BlueprintAssignable)
	FOnMeshSwitchEventBP OnMeshSwitchBP;

	UPROPERTY(BlueprintReadWrite, BlueprintAssignable)
	FOnCustomizationReadyBP OnCustomizationReady;

protected:
	UPROPERTY(BlueprintReadWrite, Transient, Instanced)
	USkinnedMeshComponent* _meshOwner;

private:
	UPROPERTY(EditAnywhere, BlueprintReadWrite, meta=(AllowPrivateAccess=true))
	TSet<ECustomizationCategory> _ignoredItemCategories;

	UPROPERTY(BlueprintReadWrite, Transient, Instanced, meta=(AllowPrivateAccess=true))
	TArray<USkeletalMeshComponent*> _cosmeticPiecesMesh;

	UPROPERTY(BlueprintReadWrite, Transient, Instanced, meta=(AllowPrivateAccess=true))
	TMap<ECustomizationCategory, USkeletalMeshComponent*> _cosmeticPiecesMeshPerCategory;

	UPROPERTY(BlueprintReadWrite, Transient, Instanced, meta=(AllowPrivateAccess=true))
	TArray<USkeletalMeshComponent*> _slaves;

	UPROPERTY(BlueprintReadWrite, Transient, meta=(AllowPrivateAccess=true))
	TMap<ECustomizationCategory, AItemVfx*> _itemVfxs;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, meta=(AllowPrivateAccess=true))
	int32 _characterIdOverride;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, meta=(AllowPrivateAccess=true))
	TMap<ECustomizationCategory, FCosmeticPieceMeshLoadingData> _cosmeticPieceMeshesBeingLoaded;

public:
	UFUNCTION(BlueprintCallable)
	void SetVfxsVisibility(ECustomizationCategory category, bool visible);

	UFUNCTION(BlueprintCallable)
	void SetMeshVisibility(bool visible);

	UFUNCTION(BlueprintCallable)
	void SetMeshOwner(USkinnedMeshComponent* mesh);

	UFUNCTION(BlueprintCallable)
	void SetCastShadow(bool castShadow);

	UFUNCTION(BlueprintCallable)
	void SetAllVfxsVisibility(bool visible);

	UFUNCTION(BlueprintCallable)
	void SetAllAccessoriesVisibility(bool visible);

	UFUNCTION(BlueprintPure)
	bool HasValidCustomization() const;

	UFUNCTION(BlueprintPure)
	USkeletalMeshComponent* GetSkeletalMesh(ECustomizationCategory category) const;

	UFUNCTION(BlueprintPure)
	bool GetMeshVisibility() const;

	UFUNCTION(BlueprintCallable)
	USkinnedMeshComponent* GetMeshOwner();

	UFUNCTION(BlueprintPure)
	TArray<FName> GetCurrentCustomizationItems() const;

	UFUNCTION(BlueprintPure)
	TArray<USkeletalMeshComponent*> GetComponents() const;

	UFUNCTION(BlueprintCallable)
	void CopyCustomization(const UCustomizedSkeletalMesh* copyFrom);

	UFUNCTION(BlueprintPure)
	bool Contains(TArray<FName> itemIds) const;

	UFUNCTION(BlueprintCallable)
	void ClearAllVfxs();

public:
	UCustomizedSkeletalMesh();
};

FORCEINLINE uint32 GetTypeHash(const UCustomizedSkeletalMesh) { return 0; }
