#pragma once

#include "CoreMinimal.h"
#include "AIPointOfInterestTargetInterface.h"
#include "Interactable.h"
#include "UObject/NoExportTypes.h"
#include "EscapeDoor.generated.h"

class UObject;
class UChargeableComponent;
class UAkComponent;
class UEscapeDoorAnimInstance;
class USceneComponent;
class USpotLightComponent;
class ASurvivor;
class UAIPerceptionStimuliSourceComponent;
class UBlockableComponent;
class ADBDPlayer;
class AActor;
class UChargeableInteractionDefinition;
class UBoxComponent;
class USkeletalMeshComponent;

UCLASS(Blueprintable)
class DEADBYDAYLIGHT_API AEscapeDoor : public AInteractable, public IAIPointOfInterestTargetInterface
{
	GENERATED_BODY()

public:
	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	TArray<FVector> EscapePositions;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	TArray<UObject*> EscapeFire;

protected:
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Instanced)
	UChargeableComponent* _killerOpenChargeable;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Instanced)
	UChargeableComponent* _openChargeable;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Instanced)
	UAkComponent* _ak_audio_escape;

	UPROPERTY(EditInstanceOnly, BlueprintReadWrite, Transient)
	UEscapeDoorAnimInstance* _escapeDoorAnimInstance;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Instanced)
	USceneComponent* _rootComponent;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, ReplicatedUsing=OnRep_Activated)
	bool _activated;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	float _beyondEscapeAreaCheckForwardOffset;

private:
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Instanced, meta=(AllowPrivateAccess=true))
	USpotLightComponent* _spotlight;

	UPROPERTY(EditInstanceOnly, Transient)
	TArray<TWeakObjectPtr<ASurvivor>> _localOverlappingSurvivors;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Instanced, meta=(AllowPrivateAccess=true))
	UAIPerceptionStimuliSourceComponent* _perceptionStimuliComponent;

	UPROPERTY(EditInstanceOnly, BlueprintReadWrite, Transient, Instanced, meta=(AllowPrivateAccess=true))
	UBlockableComponent* _doorSwitchBlockableComponent;

public:
	UFUNCTION(BlueprintCallable)
	void SetIsActivated(bool isActivated);

protected:
	UFUNCTION(BlueprintCallable, BlueprintImplementableEvent)
	void OnUnblockDoorSwitchCosmetic();

private:
	UFUNCTION(BlueprintCallable)
	void OnSpectatedPlayerChanged();

	UFUNCTION(BlueprintCallable)
	void OnRep_Activated(bool oldActivated);

protected:
	UFUNCTION(BlueprintCallable)
	void OnPlayerExitExitArea(ADBDPlayer* player);

	UFUNCTION(BlueprintCallable)
	void OnPlayerEnterExitArea(ADBDPlayer* player);

private:
	UFUNCTION(BlueprintCallable)
	void OnOpenChargeableDechargeEnd(UChargeableComponent* chargeableComponent);

	UFUNCTION(BlueprintCallable)
	void OnOpenChargeableDechargeBegin(UChargeableComponent* chargeableComponent);

public:
	UFUNCTION(BlueprintCallable, BlueprintImplementableEvent)
	void OnExitOpenChanged(bool opened);

	UFUNCTION(BlueprintCallable)
	void OnExitGateOpened(ADBDPlayer* player);

	UFUNCTION(BlueprintCallable, BlueprintImplementableEvent)
	void OnExitActivationChanged(bool activated);

protected:
	UFUNCTION(BlueprintCallable)
	void OnEscapeZoneEndOverlap(AActor* overlappingActor);

	UFUNCTION(BlueprintCallable)
	void OnEscapeZoneBeginOverlap(AActor* overlappingActor);

	UFUNCTION(BlueprintCallable, BlueprintImplementableEvent)
	void OnBlockDoorSwitchCosmetic();

public:
	UFUNCTION(BlueprintCallable, BlueprintImplementableEvent, BlueprintCosmetic)
	void LightAllLights();

	UFUNCTION(BlueprintPure)
	bool IsDoorSwitchBlocked() const;

	UFUNCTION(BlueprintPure)
	bool IsActivated() const;

	UFUNCTION(BlueprintCallable, BlueprintImplementableEvent)
	USceneComponent* GetSwitchSceneComponent() const;

	UFUNCTION(BlueprintPure, BlueprintNativeEvent)
	FVector GetParadiseServerLocation() const;

	UFUNCTION(BlueprintPure)
	float GetOpenTime() const;

	UFUNCTION(BlueprintCallable, BlueprintImplementableEvent)
	UChargeableInteractionDefinition* GetOpenEscapeInteraction();

	UFUNCTION(BlueprintPure)
	bool GetIsOpen() const;

	UFUNCTION(BlueprintPure, BlueprintImplementableEvent)
	UBoxComponent* GetExitArea() const;

	UFUNCTION(BlueprintCallable, BlueprintImplementableEvent)
	FVector GetEscapeSwitchFloorLocation() const;

	UFUNCTION(BlueprintPure, BlueprintNativeEvent)
	USkeletalMeshComponent* GetDoorSkeletalMeshComponent() const;

protected:
	UFUNCTION(BlueprintCallable, BlueprintImplementableEvent, BlueprintCosmetic)
	void Cosmetic_OnSpectatedPlayerChanged(bool isCurrentlyDecharging, bool isSurvivor);

	UFUNCTION(BlueprintCallable, BlueprintImplementableEvent, BlueprintCosmetic)
	void Cosmetic_OnGateDechargeEnd();

	UFUNCTION(BlueprintCallable, BlueprintImplementableEvent, BlueprintCosmetic)
	void Cosmetic_OnGateDechargeBegin();

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

public:
	AEscapeDoor();
};

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