#pragma once

#include "CoreMinimal.h"
#include "SpecialAttackInstigator.h"
#include "KillerAudioProxyActorInterface.h"
#include "DBDPlayer.h"
#include "DBDTunableRowHandle.h"
#include "FastTimer.h"
#include "Templates/SubclassOf.h"
#include "GameplayTagContainer.h"
#include "GameEventData.h"
#include "RangedExplosiveEffectData.h"
#include "ConjoinedTwin.generated.h"

class URangeToActorsTrackerComponent;
class UTwinOutlineUpdateStrategy;
class UAkComponent;
class UKillerBlindingFXComponent;
class UCustomizedAudioComponent;
class UDBDAttackerComponent;
class UHitValidatorComponent;
class UHitValidatorConfigurator;
class UAnimationMontageSlave;
class UTwinFirstPersonViewComponent;
class UFlashlightableComponent;
class UBlindFlashlightTargetFXComponent;
class URangedExplosiveEffectHandlerComponent;
class UStatusEffect;
class UTwinPossessNegationEffectComponent;

UCLASS(Blueprintable)
class THETWINS_API AConjoinedTwin : public ADBDPlayer, public ISpecialAttackInstigator, public IKillerAudioProxyActorInterface
{
	GENERATED_BODY()

protected:
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Instanced)
	URangeToActorsTrackerComponent* _restrictedPossessionAreaTracker;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Instanced)
	UTwinOutlineUpdateStrategy* _twinOutlineUpdateStrategy;

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

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Instanced)
	UKillerBlindingFXComponent* _twinBlindingFX;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	float TwinNoiseRange;

private:
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Instanced, meta=(AllowPrivateAccess=true))
	UCustomizedAudioComponent* _customizedAudio;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Instanced, meta=(AllowPrivateAccess=true))
	UDBDAttackerComponent* _attackerComponent;

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

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Instanced, meta=(AllowPrivateAccess=true))
	UHitValidatorComponent* _hitValidator;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Instanced, meta=(AllowPrivateAccess=true))
	UHitValidatorConfigurator* _hitValidationConfigurator;

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

	UPROPERTY(EditInstanceOnly, BlueprintReadWrite, Transient, Instanced, meta=(AllowPrivateAccess=true))
	UAnimationMontageSlave* _animationFollower;

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

	UPROPERTY(EditInstanceOnly, BlueprintReadWrite, Transient, Instanced, meta=(AllowPrivateAccess=true))
	UTwinFirstPersonViewComponent* _firstPersonViewComponent;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Instanced, meta=(AllowPrivateAccess=true))
	UFlashlightableComponent* _eyesFlashlightable;

	UPROPERTY(EditInstanceOnly, BlueprintReadWrite, Transient, Instanced, meta=(AllowPrivateAccess=true))
	UBlindFlashlightTargetFXComponent* _blindFlashlightTargetFXComponent;

	UPROPERTY(EditInstanceOnly, BlueprintReadWrite, Transient, Instanced, meta=(AllowPrivateAccess=true))
	URangedExplosiveEffectHandlerComponent* _rangedExplosiveEffectHandlerComponent;

	UPROPERTY(EditInstanceOnly, BlueprintReadWrite, Transient, meta=(AllowPrivateAccess=true))
	FFastTimer _flashlightBlindEvasionScoreTimer;

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

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

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

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

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

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

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

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

	UPROPERTY(EditInstanceOnly, BlueprintReadWrite, Transient, Instanced, meta=(AllowPrivateAccess=true))
	UTwinPossessNegationEffectComponent* _twinPossessNegationEffectComponent;

public:
	UFUNCTION(BlueprintCallable, Server, Reliable)
	void Server_SendAttackInput(bool pressed);

private:
	UFUNCTION()
	void OnFinishedPlayingEvent(const FGameplayTag gameEventType, const FGameEventData& gameEventData);

protected:
	UFUNCTION(BlueprintCallable, BlueprintImplementableEvent, BlueprintCosmetic)
	void Cosmetic_OnOnGroundUncontrolledChanged(bool onGroundAndUncontrolled);

	UFUNCTION(BlueprintCallable)
	void Authority_OnFirecrackerInRangeBegin(const FRangedExplosiveEffectData& effectData);

public:
	AConjoinedTwin();
};

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