#pragma once

#include "CoreMinimal.h"
#include "ChargeableInteractionDefinition.h"
#include "DBDTunableRowHandle.h"
#include "GameplayTagContainer.h"
#include "TunableStat.h"
#include "K36SpellActivationData.h"
#include "K36SpellSpeedCurveTypeData.h"
#include "K36SpellSpeedCurveData.h"
#include "EK36SpellSpeedCurveType.h"
#include "EK36SpellCooldownType.h"
#include "K36SpellInteraction.generated.h"

class AKiller;
class UChargeableComponent;
class UK36SpellData;
class UTimerObject;
class UObject;

UCLASS(Blueprintable, Abstract, EditInlineNew, meta=(BlueprintSpawnableComponent))
class THEK36_API UK36SpellInteraction : public UChargeableInteractionDefinition
{
	GENERATED_BODY()

protected:
	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	FDBDTunableRowHandle _chargeSpellTime;

	UPROPERTY(EditAnywhere)
	FGameplayTag _isChargingSpellStateTag;

	UPROPERTY(EditAnywhere)
	FGameplayTag _isSpellChargedStateTag;

	UPROPERTY(EditAnywhere)
	FGameplayTag _isActivatingSpellStateTag;

	UPROPERTY(EditAnywhere)
	FGameplayTag _isSpellOnNonCancelledCooldownStateTag;

	UPROPERTY(EditAnywhere)
	FGameplayTag _spellChargeStartGameEvent;

	UPROPERTY(EditAnywhere)
	FGameplayTag _spellTriggeredGameEvent;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	FDBDTunableRowHandle _activationTime;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	FDBDTunableRowHandle _activatedExitDuration;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	FDBDTunableRowHandle _cancelExitDuration;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	FTunableStat _initialSpellCooldown;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	FTunableStat _activatedSpellCooldownTime;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	FDBDTunableRowHandle _cancelledSpellCooldownTime;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, ReplicatedUsing=OnRep_OwningKiller)
	TWeakObjectPtr<AKiller> _owningKiller;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	bool _endInteractionOnSpellActivated;

private:
	UPROPERTY(EditAnywhere, BlueprintReadWrite, ReplicatedUsing=OnRep_SpellActivationData, meta=(AllowPrivateAccess=true))
	FK36SpellActivationData _spellActivationData;

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

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

	UPROPERTY(EditAnywhere, BlueprintReadWrite, ReplicatedUsing=OnRep_ReplicatedChargeableComponent, Instanced, meta=(AllowPrivateAccess=true))
	UChargeableComponent* _replicatedChargeableComponent;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Replicated, meta=(AllowPrivateAccess=true))
	UK36SpellData* _spellData;

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

	UPROPERTY(EditAnywhere, BlueprintReadWrite, meta=(AllowPrivateAccess=true))
	TSet<FK36SpellSpeedCurveTypeData> _speedCurvesData;

	UPROPERTY(EditInstanceOnly, BlueprintReadWrite, Transient, meta=(AllowPrivateAccess=true))
	TMap<EK36SpellSpeedCurveType, FK36SpellSpeedCurveData> _speedCurveMappedData;

private:
	UFUNCTION(BlueprintCallable, Server, Reliable, WithValidation)
	void Server_ActivateSpell(AKiller* killer, UObject* customObjectParameter);

	UFUNCTION(BlueprintCallable)
	void OnRep_SpellActivationData(FK36SpellActivationData previousActivationData);

	UFUNCTION(BlueprintCallable)
	void OnRep_ReplicatedChargeableComponent();

protected:
	UFUNCTION(BlueprintCallable)
	void OnRep_OwningKiller();

private:
	UFUNCTION(BlueprintCallable)
	void OnRep_CooldownTimer();

	UFUNCTION(BlueprintCallable, NetMulticast, Reliable)
	void Multicast_TriggerCooldownTimer(float cooldownTime, EK36SpellCooldownType cooldownType);

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

public:
	UK36SpellInteraction();
};

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