// Copyright Epic Games, Inc. All Rights Reserved.
// UE5 Modular Game Framework — DA_ItemData Implementation

#include "Inventory/DA_ItemData.h"
#include "GameplayTagsManager.h"

DEFINE_LOG_CATEGORY_STATIC(LogItemData, Log, All);

UDA_ItemData::UDA_ItemData()
{
	ItemType = EItemType::Misc;
	StackLimit = 1;
	Weight = 0.0f;
	bCanBeDropped = true;
	bIsKeyItem = false;
	bHasInspectMode = false;
}

// ============================================================================
// Overrides
// ============================================================================

void UDA_ItemData::PostLoad()
{
	Super::PostLoad();

	// Key items cannot be dropped — enforce.
	if (bIsKeyItem && bCanBeDropped)
	{
		UE_LOG(LogItemData, Warning, TEXT("DA_ItemData::PostLoad — '%s': bIsKeyItem && bCanBeDropped — forcing bCanBeDropped = false"),
			*ItemTag.GetTagName().ToString());
		bCanBeDropped = false;
	}

	// Validate tag registration.
	if (ItemTag.IsValid())
	{
		UGameplayTagsManager& TagManager = UGameplayTagsManager::Get();
		FGameplayTag CheckTag = TagManager.RequestGameplayTag(ItemTag.GetTagName(), false);
		if (!CheckTag.IsValid())
		{
			UE_LOG(LogItemData, Warning, TEXT("DA_ItemData::PostLoad — '%s': ItemTag '%s' is not registered in the tag table!"),
				*GetName(), *ItemTag.GetTagName().ToString());
		}
	}
}

#if WITH_EDITOR
void UDA_ItemData::PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent)
{
	Super::PostEditChangeProperty(PropertyChangedEvent);

	FName PropertyName = PropertyChangedEvent.GetPropertyName();

	// Auto-enforce key item rule.
	if (PropertyName == GET_MEMBER_NAME_CHECKED(UDA_ItemData, bIsKeyItem) && bIsKeyItem)
	{
		bCanBeDropped = false;
	}
}

bool UDA_ItemData::ValidateItemData(FString& OutErrors) const
{
	TArray<FString> Errors;

	// Check required fields.
	if (!ItemTag.IsValid())
	{
		Errors.Add(TEXT("ItemTag is invalid/empty."));
	}

	if (DisplayName.IsEmpty())
	{
		Errors.Add(TEXT("DisplayName is empty."));
	}

	if (Description.IsEmpty())
	{
		Errors.Add(TEXT("Description is empty."));
	}

	// Check key item cannot be dropped.
	if (bIsKeyItem && bCanBeDropped)
	{
		Errors.Add(TEXT("bIsKeyItem is true but bCanBeDropped is also true. Key items cannot be dropped."));
	}

	// Check consumable has valid data.
	if (ItemType == EItemType::Consumable &&
		ConsumableData.HealthRestore <= 0.0f && ConsumableData.StressReduce <= 0.0f)
	{
		Errors.Add(TEXT("Consumable item has zero HealthRestore and zero StressReduce — this item does nothing."));
	}

	// Check weapon has damage.
	if (ItemType == EItemType::Weapon && EquipmentData.Damage <= 0.0f)
	{
		Errors.Add(TEXT("Weapon item has zero Damage."));
	}

	// Check stack limits.
	if (StackLimit < 1)
	{
		Errors.Add(TEXT("StackLimit must be >= 1."));
	}

	// Build output string.
	for (const FString& Err : Errors)
	{
		OutErrors += TEXT("- ") + Err + TEXT("\n");
	}

	if (Errors.Num() > 0)
	{
		UE_LOG(LogItemData, Warning, TEXT("DA_ItemData::ValidateItemData — '%s' has %d errors:\n%s"),
			*ItemTag.GetTagName().ToString(), Errors.Num(), *OutErrors);
	}

	return Errors.Num() == 0;
}
#endif
