#pragma once

#include "CoreMinimal.h"
#include "SpecialBehaviourInteractable.h"
#include "DBDTunableRowHandle.h"
#include "GameplayTagContainer.h"
#include "UnstableRift.generated.h"

class UUnstableRiftInteraction;
class UChargeableComponent;
class UInteractor;
class UPrimitiveComponent;
class UDBDOutlineComponent;
class UUnstableRiftOutlineStrategy;
class UStaticMeshComponent;
class ULinkedTeleporterComponent;
class UNearTrackedActorComponent;
class UAkAudioEvent;
class USpawnElementTrackerComponent;
class AActor;
class ADBDPlayer;

UCLASS(Blueprintable)
class HALLOWEEN_API AUnstableRift : public ASpecialBehaviourInteractable
{
	GENERATED_BODY()

private:
	UPROPERTY(EditAnywhere, BlueprintReadWrite, meta=(AllowPrivateAccess=true))
	bool _isInitialized;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, ReplicatedUsing=OnRep_IsDepositEnergyInteractionAvailable, meta=(AllowPrivateAccess=true))
	bool _isDepositEnergyInteractionAvailable;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Replicated, meta=(AllowPrivateAccess=true))
	bool _isPortalOpened;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, NoClear, Instanced, meta=(AllowPrivateAccess=true))
	UUnstableRiftInteraction* _unstableRiftInteractionSurvivor;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, NoClear, Instanced, meta=(AllowPrivateAccess=true))
	UUnstableRiftInteraction* _unstableRiftInteractionKiller;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, NoClear, Instanced, meta=(AllowPrivateAccess=true))
	UChargeableComponent* _unstableRiftInteractionChargeable;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, NoClear, Instanced, meta=(AllowPrivateAccess=true))
	UInteractor* _unstableRiftInteractor;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, NoClear, Instanced, meta=(AllowPrivateAccess=true))
	UPrimitiveComponent* _unstableRiftInteractionZone;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, NoClear, Instanced, meta=(AllowPrivateAccess=true))
	UDBDOutlineComponent* _outlineComponent;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, NoClear, Instanced, meta=(AllowPrivateAccess=true))
	UDBDOutlineComponent* _teleporterOutlineComponent;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, NoClear, Instanced, meta=(AllowPrivateAccess=true))
	UUnstableRiftOutlineStrategy* _outlineStrategy;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, NoClear, Instanced, meta=(AllowPrivateAccess=true))
	UUnstableRiftOutlineStrategy* _teleporterOutlineStrategy;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Instanced, meta=(AllowPrivateAccess=true))
	UStaticMeshComponent* _unstableRiftMesh;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Instanced, meta=(AllowPrivateAccess=true))
	UStaticMeshComponent* _teleporterMesh;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Instanced, meta=(AllowPrivateAccess=true))
	ULinkedTeleporterComponent* _linkedTeleporter;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Instanced, meta=(AllowPrivateAccess=true))
	UNearTrackedActorComponent* _nearTrackedActorAudioComponent;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, meta=(AllowPrivateAccess=true))
	FDBDTunableRowHandle _offeringDirectionalAudioCueDistance;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, meta=(AllowPrivateAccess=true))
	FDBDTunableRowHandle _voidEnergyNeededToOpenRift;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, meta=(AllowPrivateAccess=true))
	UAkAudioEvent* _offeringAudioEvent;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Instanced, meta=(AllowPrivateAccess=true))
	UNearTrackedActorComponent* _nearTrackedActorItemPreventionComponent;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, meta=(AllowPrivateAccess=true))
	float _rangeToPreventItemDrop;

	UPROPERTY(EditAnywhere)
	TArray<FGameplayTag> _stateTagsToGivePlayersOnItemDropPreventionArea;

	UPROPERTY(BlueprintReadWrite, Transient, Instanced, meta=(AllowPrivateAccess=true))
	USpawnElementTrackerComponent* _spawnElementTrackerComponent;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, meta=(AllowPrivateAccess=true))
	float _maxDistanceToFollowPlayer;

private:
	UFUNCTION(BlueprintCallable)
	void OnRep_IsDepositEnergyInteractionAvailable();

	UFUNCTION(BlueprintCallable)
	void OnIntroCompleted();

	UFUNCTION(BlueprintCallable)
	void OnInRangeChanged(bool isWithinRange, const AActor* trackedActor);

protected:
	UFUNCTION(BlueprintCallable, BlueprintImplementableEvent, BlueprintCosmetic)
	void Cosmetic_OnStoppedInteracting();

	UFUNCTION(BlueprintCallable, BlueprintImplementableEvent, BlueprintCosmetic)
	void Cosmetic_OnStartedInteracting(ADBDPlayer* interactingPlayer, float interactionDuration);

	UFUNCTION(BlueprintCallable, BlueprintImplementableEvent, BlueprintCosmetic)
	void Cosmetic_OnInteractionCompleted(ADBDPlayer* interactingPlayer);

	UFUNCTION(BlueprintCallable, BlueprintImplementableEvent, BlueprintCosmetic)
	void Cosmetic_ChangeUnstableVisibility(bool isVisible);

public:
	virtual void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const override;

public:
	AUnstableRift();
};

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