#pragma once

#include "CoreMinimal.h"
#include "ChargeableProgressSource.h"
#include "Components/ActorComponent.h"
#include "BlueprintAudioEvent.h"
#include "ESkillCheckCustomType.h"
#include "WiggleComponent.generated.h"

class UChargeableComponent;
class AKiller;
class UInputComponent;
class ADBDPlayer;

UCLASS(Blueprintable, meta=(BlueprintSpawnableComponent))
class DBDGAMEPLAY_API UWiggleComponent : public UActorComponent, public IChargeableProgressSource
{
	GENERATED_BODY()

protected:
	UPROPERTY(BlueprintReadWrite, BlueprintAssignable)
	FBlueprintAudioEvent OnFailSkillCheckAudioEvent;

	UPROPERTY(BlueprintReadWrite, BlueprintAssignable)
	FBlueprintAudioEvent OnMissSkillCheckAudioEvent;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	FString AUDIO_EVENT_SKILL_CHECK_WARNING;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	FString AUDIO_EVENT_SKILL_CHECK_GOOD;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	FString AUDIO_EVENT_SKILL_CHECK_GREAT;

private:
	UPROPERTY(EditInstanceOnly, BlueprintReadWrite, Transient, Instanced, meta=(AllowPrivateAccess=true))
	UChargeableComponent* _wiggleProgress;

	UPROPERTY(EditInstanceOnly, BlueprintReadWrite, Transient, meta=(AllowPrivateAccess=true))
	TWeakObjectPtr<AKiller> _killerWigglingFrom;

	UPROPERTY(EditInstanceOnly, BlueprintReadWrite, Transient, Export, meta=(AllowPrivateAccess=true))
	TWeakObjectPtr<UInputComponent> _inputComponent;

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

private:
	UFUNCTION(BlueprintCallable)
	void OnWiggleSkillCheckEnd(bool hadInput, bool success, bool bonus, ESkillCheckCustomType type, ADBDPlayer* player);

	UFUNCTION(BlueprintCallable)
	void OnWiggleInput();

	UFUNCTION(BlueprintCallable)
	void OnWiggleEnd();

	UFUNCTION(BlueprintCallable)
	void OnSurvivorHookedOrUnhookedOrDropped();

	UFUNCTION(BlueprintCallable)
	void OnPlayerPickedUpStart(ADBDPlayer* picker);

	UFUNCTION(BlueprintCallable)
	void OnPlayerPickedUpEnd(ADBDPlayer* picker);

	UFUNCTION(BlueprintCallable)
	void OnPickedUpSkillCheckEnd(bool hadInput, bool success, bool bonus, ESkillCheckCustomType type, ADBDPlayer* player);

	UFUNCTION(BlueprintCallable)
	void OnLevelReadyToPlay();

	UFUNCTION(BlueprintCallable)
	void OnKeyBindingsChanged();

	UFUNCTION(BlueprintCallable)
	void OnHideWiggleSkillCheck(ESkillCheckCustomType type);

public:
	UFUNCTION(BlueprintPure)
	UChargeableComponent* GetWiggleChargeable() const;

	UFUNCTION(BlueprintCallable, Exec)
	void DBD_SetWiggleProgress(const float progressPercent) const;

	UFUNCTION(BlueprintCallable)
	void Authority_TutorialEndWiggle();

	UFUNCTION(BlueprintCallable)
	void Authority_AddWiggleCharge(float chargeAmount);

public:
	UWiggleComponent();
};

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