#pragma once

#include "CoreMinimal.h"
#include "Perk.h"
#include "Templates/SubclassOf.h"
#include "DBDTunableRowHandle.h"
#include "S42P02.generated.h"

class US42P02Interaction;
class UStatusEffect;
class AS42P02TrackSelectionManager;
class UInteractionAttacherComponent;
class UBaseLingeringStatusEffect;
class UChargeableComponent;
class ADBDPlayer;

UCLASS(Blueprintable, meta=(BlueprintSpawnableComponent))
class THES42_API US42P02 : public UPerk
{
	GENERATED_BODY()

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

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

	UPROPERTY(EditAnywhere)
	float _cooldownDuration;

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

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

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

	UPROPERTY(EditAnywhere, BlueprintReadWrite, meta=(AllowPrivateAccess=true))
	TSubclassOf<UStatusEffect> _s42p02StatusEffectClass;

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

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

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

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

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

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

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

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

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

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

	UPROPERTY(EditAnywhere, BlueprintReadWrite, ReplicatedUsing=OnRep_TrackSelectionManager, meta=(AllowPrivateAccess=true))
	AS42P02TrackSelectionManager* _trackSelectionManager;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, ReplicatedUsing=OnRep_DiceRandomValue, meta=(AllowPrivateAccess=true))
	int32 _diceRandomValue;

	UPROPERTY(BlueprintReadWrite, ReplicatedUsing=OnRep_InteractionAttacherComponent, Transient, Instanced, meta=(AllowPrivateAccess=true))
	UInteractionAttacherComponent* _interactionAttacherComponent;

	UPROPERTY(BlueprintReadWrite, Transient, Instanced, meta=(AllowPrivateAccess=true))
	US42P02Interaction* _interaction;

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

	UPROPERTY(BlueprintReadWrite, Transient, Instanced, meta=(AllowPrivateAccess=true))
	UChargeableComponent* _S42P02ChargeableComponent;

private:
	UFUNCTION(BlueprintCallable)
	void OnRep_TrackSelectionManager();

	UFUNCTION(BlueprintCallable)
	void OnRep_InteractionAttacherComponent();

	UFUNCTION(BlueprintCallable)
	void OnRep_DiceRandomValue();

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

	UFUNCTION(BlueprintCallable, NetMulticast, Reliable)
	void Multicast_OnPlayerScreaming(ADBDPlayer* player);

public:
	UFUNCTION(BlueprintPure)
	float GetCooldownDurationAtLevel() const;

	UFUNCTION(BlueprintCallable, BlueprintImplementableEvent, BlueprintCosmetic)
	void Cosmetic_S42P02PerkLoadedInGame(const TArray<ADBDPlayer*>& order);

private:
	UFUNCTION(BlueprintCallable)
	void Authority_OnLevelReadyToPlay();

	UFUNCTION(BlueprintCallable)
	void Authority_OnInteractionStarted();

	UFUNCTION(BlueprintCallable)
	void Authority_OnInteractionDone();

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

public:
	US42P02();
};

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