// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "StatForgeDefs.h"
#include "UObject/Object.h"
#include "GameplayStatEffect.generated.h"

class UGameplayStatEffect;

UENUM(BlueprintType)
enum class EModOperation : uint8
{
	Add,
	MultiplyAdditive	UMETA(DisplayName = "Multiply Additive"),
	MultiplyCompound	UMETA(DisplayName = "Multiply Compound"),
	Override
};

static constexpr float GameplayStatEffectDuration_Instant = 0.f;

UENUM(BlueprintType)
enum class EGameplayStatEffectModCalculation : uint8
{
	Flat,
	CalculationClass,
	DataValue
};

USTRUCT(BLueprintType)
struct STATFORGE_API FGameplayStatEffectMod
{
	GENERATED_BODY()
	
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Stat Forge|Stats", meta = (GetOptions = "StatForgeDeveloperSettings.GetStatNames"))
	FName AffectedStat;
	
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Stat Forge|Stats")
	EModOperation ModOperation;
	
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Stat Forge|Stats")
	EGameplayStatEffectModCalculation CalculationType;
	
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Stat Forge|Stats", meta = (EditCondition = "CalculationType==EGameplayStatEffectModCalculation::Flat", EditConditionHides))
	float FlatValue = 0.f;
	
	UPROPERTY(EditAnywhere, Category = "Stat Forge|Stats", meta = (EditCondition = "CalculationType==EGameplayStatEffectModCalculation::CalculationClass", EditConditionHides, BlueprintBaseOnly, ShowTreeView))
	TSubclassOf<class UStatEffectModCalculation> StatCalculationClass;
	
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Stat Forge|Stats", meta = (EditCondition = "CalculationType==EGameplayStatEffectModCalculation::DataValue", EditConditionHides))
	FName DataValueName;
	
	float GetModValue(UStatForgeComponent* StatComponent, const TMap<FName, float>& DataValueMap) const;
};

/**
 * 
 */
UCLASS(Blueprintable)
class STATFORGE_API UGameplayStatEffect : public UObject
{
	GENERATED_BODY()
public:
	
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Duration")
	float Duration = 0.f;
	
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Duration")
	float TickPeriod = 0.f;
	
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Modifiers")
	TArray<FGameplayStatEffectMod> Modifiers;
	
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Tags")
	FGameplayTagContainer EffectTags;
	
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Tags")
	FGameplayTagContainer CharacterTags;
	
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Tags|Requirements", meta = (EditCondition = "Duration==0"))
	FGameplayTagContainer TagsRequiredToApply;
	
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Tags|Requirements", meta = (EditCondition = "Duration!=0"))
	FGameplayTagContainer TagsRequiredToTick;
	
	UFUNCTION(BlueprintCallable, Category = "Stat Forge|Effect")
	void AppendDataValueMap(TMap<FName, float> InDataValueMap) { DataValueMap.Append(InDataValueMap); }
	
	const TMap<FName, float>& GetDataValueMap() { return DataValueMap; }
	
protected:
	
	UPROPERTY()
	TMap<FName, float> DataValueMap;
};
