// © 2025 Naked People Team. All Rights Reserved.


#include "EquipClothingRestriction.h"
#include "NakedDesire/Clothing/ClothingItem.h"
#include "NakedDesire/Clothing/ClothingItemInstance.h"
#include "NakedDesire/Clothing/ClothingManager.h"
#include "NakedDesire/Player/NakedDesireCharacter.h"

#define LOCTEXT_NAMESPACE "Missions.Restriction.EquipClothing"
const FText RestrictionEquipClothingDescriptionSingle = LOCTEXT("Description.Single", "Equip {ItemName}");
const FText RestrictionEquipClothingDescriptionMultiple = LOCTEXT("Description.Multiple", "Equip one of: {ItemNames}");
#undef LOCTEXT_NAMESPACE

void UEquipClothingRestriction::Init(ANakedDesireCharacter* PlayerCharacter)
{
	Super::Init(PlayerCharacter);

	if (!ClothingEquippedDelegateHandle.IsValid())
	{
		Player->ClothingManager->OnClothingEquip.AddUniqueDynamic(this, &UEquipClothingRestriction::OnClothingEquipped);
	}

	if (!ClothingUnequippedDelegateHandle.IsValid())
	{
		Player->ClothingManager->OnClothingUnequip.AddUniqueDynamic(this, &UEquipClothingRestriction::OnClothingUnequipped);
	}

	CheckClothing();
}

void UEquipClothingRestriction::Stop()
{
	Super::Stop();

	Player->ClothingManager->OnClothingEquip.Remove(this, TEXT("OnClothingEquipped"));
	Player->ClothingManager->OnClothingUnequip.Remove(this, TEXT("OnClothingUnequipped"));
}

FText UEquipClothingRestriction::GetDescription() const
{
	if (ClothingItems.Num() == 1 && ClothingItems[0])
	{
		return FText::Format(RestrictionEquipClothingDescriptionSingle,
			FFormatNamedArguments
			{
				{TEXT("ItemName"), ClothingItems[0]->Name}
			});
	}

	FString Items = TEXT("");
	for (const auto& Item : ClothingItems)
	{
		if (Item)
		{
			Items += Item->Name.ToString() + ", ";
		}
	}
	return FText::Format(RestrictionEquipClothingDescriptionMultiple,
			FFormatNamedArguments
			{
				{TEXT("ItemNames"), FText::FromString(Items)}
			});
}

void UEquipClothingRestriction::OnClothingEquipped(const UClothingItemInstance* ClothingItemInstance)
{
	const bool IsTargetClothing = ClothingItems.FindByPredicate([&ClothingItemInstance](const UClothingItem* Item)
	{
		return Item && Item->Name.EqualTo(ClothingItemInstance->GetClothingItem()->Name);
	}) != nullptr;
	if (IsTargetClothing)
	{
		Complete();
	}
}

void UEquipClothingRestriction::OnClothingUnequipped(const UClothingItemInstance* ClothingItemInstance)
{
	const bool IsTargetClothing = ClothingItems.FindByPredicate([&ClothingItemInstance](const UClothingItem* Item)
	{
		return Item && Item->Name.EqualTo(ClothingItemInstance->GetClothingItem()->Name);
	}) != nullptr;
	if (IsTargetClothing)
	{
		Init(Player);
	}
}

void UEquipClothingRestriction::CheckClothing()
{
	for (const FClothingSlotData& ClothingSlot : Player->ClothingManager->ClothingSlots)
	{
		if (!ClothingSlot.ClothingItemInstance)
		{
			continue;
		}
		
		const bool IsTargetClothing = ClothingItems.FindByPredicate([&ClothingSlot](const UClothingItem* Item)
		{
			return Item && Item->Name.EqualTo(ClothingSlot.ClothingItemInstance->GetClothingItem()->Name);
		}) != nullptr;
		if (IsTargetClothing)
		{
			Complete();
			return;
		}
	}
}
