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

#include "Config/StatForgeDeveloperSettings.h"
#include "Data/StatForgeRegistry.h"

#if WITH_EDITOR
void UStatForgeDeveloperSettings::PostEditChangeProperty(struct FPropertyChangedEvent& PropertyChangedEvent)
{
	Super::PostEditChangeProperty(PropertyChangedEvent);
	
	if (PropertyChangedEvent.GetPropertyName() == GET_MEMBER_NAME_CHECKED(UStatForgeDeveloperSettings, StatMap))
	{
		TSet<FName> Seen;
		for (int32 i = StatMap.Num() - 1; i >= 0; i--)
		{
			if (StatMap[i].StatName.IsNone())
			{
				continue;
			}
            
			if (Seen.Contains(StatMap[i].StatName))
			{
				FMessageDialog::Open(EAppMsgType::Ok,
					FText::Format(INVTEXT("StatForge: Duplicate stat name '{0}' removed."),FText::FromName(StatMap[i].StatName)));
				StatMap.RemoveAt(i);
			}
			else
			{
				Seen.Add(StatMap[i].StatName);
			}
		}
	}
}

void UStatForgeDeveloperSettings::PostReloadConfig(class FProperty* PropertyThatWasLoaded)
{
	Super::PostReloadConfig(PropertyThatWasLoaded);
	MergeRegistryIntoStatMap();
}
#endif

FStatDef UStatForgeDeveloperSettings::GetStatByName(FName StatName) const
{
	for (const FStatDef Def : StatMap)
	{
		if (Def.StatName == StatName)
		{
			return Def;
		}
	}
	
	return FStatDef();
}

TArray<FName> UStatForgeDeveloperSettings::GetStatNames()
{
	TArray<FName> Names;
	
	if (const UStatForgeDeveloperSettings* Settings = GetDefault<UStatForgeDeveloperSettings>())
	{
		for (const FStatDef Def : Settings->StatMap)
		{
			Names.Add(Def.StatName);
		}
	}
	
	return Names;
}

const FStatDef* UStatForgeDeveloperSettings::FindStat(const FName& StatName) const
{
	return StatMap.FindByPredicate([&](const FStatDef& Def)
	{
		return Def.StatName == StatName;
	});
}

void UStatForgeDeveloperSettings::PostInitProperties()
{
	Super::PostInitProperties();
	MergeRegistryIntoStatMap();
}

void UStatForgeDeveloperSettings::MergeRegistryIntoStatMap()
{
	UE_LOG(LogTemp, Warning, TEXT("StatForge: Merging, registry has %d stats"), FStatForgeRegistry::Get().Num());

	for (const FStatDef& Registered : FStatForgeRegistry::Get())
	{
		const bool bExists = StatMap.ContainsByPredicate([&](const FStatDef& Def)
		{
			return Def.StatName == Registered.StatName;
		});
		
		if (!bExists)
		{
			StatMap.Add(Registered);
		}
	}
}
