#pragma once

#include "CoreMinimal.h"
#include "Components/ActorComponent.h"
#include "Templates/SubclassOf.h"
#include "DBDTunableRowHandle.h"
#include "GameplayTagContainer.h"
#include "EHealthState.h"
#include "ImpactInfo.h"
#include "SnowballPlayerComponent.generated.h"

class UTimerObject;
class ASnowballLauncherController;
class UThrowSnowballInteraction;
class ADBDPlayer;

UCLASS(Blueprintable, meta=(BlueprintSpawnableComponent))
class WINTEREVENT2023_API USnowballPlayerComponent : public UActorComponent
{
	GENERATED_BODY()

private:
	UPROPERTY(BlueprintReadWrite, ReplicatedUsing=OnRep_CooldownTimer, Transient, Instanced, meta=(AllowPrivateAccess=true))
	UTimerObject* _cooldownTimer;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, meta=(AllowPrivateAccess=true))
	TSubclassOf<ASnowballLauncherController> _snowballLauncherControllerClass;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, meta=(AllowPrivateAccess=true))
	TSubclassOf<UThrowSnowballInteraction> _snowballThrowingInteractionClassSurvivor;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, meta=(AllowPrivateAccess=true))
	TSubclassOf<UThrowSnowballInteraction> _snowballThrowingInteractionClassKiller;

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

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

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

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

	UPROPERTY(EditAnywhere, BlueprintReadWrite, meta=(AllowPrivateAccess=true))
	FGameplayTagContainer _hideVignetteVFXTags;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, meta=(AllowPrivateAccess=true))
	FGameplayTagContainer _hidePlayerVFXTags;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, ReplicatedUsing=OnRep_SnowballLauncherController, meta=(AllowPrivateAccess=true))
	ASnowballLauncherController* _snowballLauncherController;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, ReplicatedUsing=OnRep_SnowballThrowInteraction, Instanced, meta=(AllowPrivateAccess=true))
	UThrowSnowballInteraction* _snowballThrowInteraction;

private:
	UFUNCTION(BlueprintCallable)
	void OnRep_SnowballThrowInteraction();

	UFUNCTION(BlueprintCallable)
	void OnRep_SnowballLauncherController();

	UFUNCTION(BlueprintCallable)
	void OnRep_CooldownTimer();

	UFUNCTION(BlueprintCallable)
	void OnOwningCamperGuidedStateChanged();

	UFUNCTION(BlueprintCallable)
	void OnIntroComplete();

	UFUNCTION(BlueprintCallable)
	void OnCamperDamageStateChanged(EHealthState oldDamageState, EHealthState newDamageState);

protected:
	UFUNCTION(BlueprintCallable, BlueprintImplementableEvent, BlueprintCosmetic)
	void Cosmetic_OnVFXVignetteTagAddedOrRemoved(ADBDPlayer* player, bool added);

	UFUNCTION(BlueprintCallable, BlueprintImplementableEvent, BlueprintCosmetic)
	void Cosmetic_OnThrownSnowballHitPlayer(ADBDPlayer* owningPlayer, ADBDPlayer* hitPlayer);

	UFUNCTION(BlueprintCallable, BlueprintImplementableEvent, BlueprintCosmetic)
	void Cosmetic_OnThrownSnowballHitCollision(ADBDPlayer* owningPlayer, FImpactInfo impactInfo);

	UFUNCTION(BlueprintCallable, BlueprintImplementableEvent, BlueprintCosmetic)
	void Cosmetic_OnSnowballThrowStart(ADBDPlayer* owningPlayer);

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

	UFUNCTION(BlueprintCallable, BlueprintImplementableEvent, BlueprintCosmetic)
	void Cosmetic_OnSnowballsDepleted(ADBDPlayer* owningPlayer);

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

	UFUNCTION(BlueprintCallable, BlueprintImplementableEvent, BlueprintCosmetic)
	void Cosmetic_OnPlayerVFXTagAddedOrRemoved(ADBDPlayer* player, bool added);

	UFUNCTION(BlueprintCallable, BlueprintImplementableEvent, BlueprintCosmetic)
	void Cosmetic_OnPlayerUnhidden(ADBDPlayer* owningPlayer);

	UFUNCTION(BlueprintCallable, BlueprintImplementableEvent, BlueprintCosmetic)
	void Cosmetic_OnPlayerHidden(ADBDPlayer* owningPlayer);

	UFUNCTION(BlueprintCallable, BlueprintImplementableEvent, BlueprintCosmetic)
	void Cosmetic_OnPlayerDiedOrBeingKilled(ADBDPlayer* deadPlayer);

	UFUNCTION(BlueprintCallable, BlueprintImplementableEvent, BlueprintCosmetic)
	void Cosmetic_OnLocallyObservedChanged(bool isLocallyObserved, ADBDPlayer* owningPlayer);

	UFUNCTION(BlueprintCallable, BlueprintImplementableEvent, BlueprintCosmetic)
	void Cosmetic_OnCamperPickUpEndOrDropped(ADBDPlayer* pickedUpPlayer);

	UFUNCTION(BlueprintCallable, BlueprintImplementableEvent, BlueprintCosmetic)
	void Cosmetic_OnCamperPickedUp(ADBDPlayer* pickedUpPlayer);

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

public:
	USnowballPlayerComponent();
};

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