#pragma once

#include "CoreMinimal.h"
#include "Components/ActorComponent.h"
#include "Templates/SubclassOf.h"
#include "HalloweenEventComponent.generated.h"

class AActor;
class UVoidZonePlayerComponent;
class USpawnHauntProjectileInteraction;
class UHauntProjectilePlayerInventoryComponent;
class USpecialEventVFXHelperComponent;
class AUnstableRift;
class ADBDPlayer;
class ULocalPlayerTrackerComponent;
class ULinkedTeleporterComponent;

UCLASS(Blueprintable, meta=(BlueprintSpawnableComponent))
class HALLOWEEN_API UHalloweenEventComponent : public UActorComponent
{
	GENERATED_BODY()

private:
	UPROPERTY(EditAnywhere, BlueprintReadWrite, meta=(AllowPrivateAccess=true))
	TSubclassOf<AActor> _voidWorldTeleporterBP;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, meta=(AllowPrivateAccess=true))
	TSubclassOf<UVoidZonePlayerComponent> _voidZonePlayerComponentClass;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, meta=(AllowPrivateAccess=true))
	TSubclassOf<USpawnHauntProjectileInteraction> _spawnHauntProjectileClass;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, meta=(AllowPrivateAccess=true))
	TSubclassOf<UHauntProjectilePlayerInventoryComponent> _hauntProjectilePlayerInventoryComponentClass;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, meta=(AllowPrivateAccess=true))
	TSubclassOf<USpecialEventVFXHelperComponent> _vfxHelperComponent;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, meta=(AllowPrivateAccess=true))
	TSubclassOf<UActorComponent> _eventCheatComponentClass;

	UPROPERTY(BlueprintReadWrite, Transient, meta=(AllowPrivateAccess=true))
	TArray<AUnstableRift*> _unstableRifts;

	UPROPERTY(BlueprintReadWrite, ReplicatedUsing=OnRep_VoidWorldTeleporterActors, Transient, meta=(AllowPrivateAccess=true))
	TArray<AActor*> _voidWorldTeleporterActors;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, ReplicatedUsing=OnRep_PlayersInVoid, meta=(AllowPrivateAccess=true))
	TArray<ADBDPlayer*> _playersInVoid;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, meta=(AllowPrivateAccess=true))
	TArray<ADBDPlayer*> _previousPlayersInVoidZone;

	UPROPERTY(BlueprintReadWrite, Transient, Instanced, meta=(AllowPrivateAccess=true))
	ULocalPlayerTrackerComponent* _localPlayerTracker;

private:
	UFUNCTION(BlueprintCallable)
	void OnRep_VoidWorldTeleporterActors();

	UFUNCTION(BlueprintCallable)
	void OnRep_PlayersInVoid();

protected:
	UFUNCTION(BlueprintCallable, BlueprintImplementableEvent, BlueprintCosmetic)
	void Cosmetic_OnPlayerTeleported(ADBDPlayer* playerTeleported, bool teleportIntoVoid);

public:
	UFUNCTION(BlueprintCallable)
	void Authority_TurnAllRiftsIntoTeleporters(bool turnOnTeleporters);

	UFUNCTION(BlueprintCallable)
	void Authority_PlayerTeleportedOutOfVoidZone(ADBDPlayer* playerTeleported);

private:
	UFUNCTION(BlueprintCallable)
	void Authority_PlayerTeleportedInToVoidZone(ADBDPlayer* playerTeleported, ULinkedTeleporterComponent* teleporterUsed);

public:
	UFUNCTION(BlueprintCallable)
	void Authority_PlayerPreTeleportOutOfVoidZone(ADBDPlayer* playerTeleported);

private:
	UFUNCTION(BlueprintCallable)
	void Authority_PlayerPreTeleportInToVoidZone(ADBDPlayer* playerTeleported);

	UFUNCTION(BlueprintCallable)
	void Authority_OnLevelReadyToPlay();

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

public:
	UHalloweenEventComponent();
};

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