// Copyright ExByte Studios. Item Interaction Ecosystem.

#pragma once

#include "CoreMinimal.h"
#include "GameplayTagContainer.h"
#include "ItemEnums.h"
#include "InventoryContainer.generated.h"

/**
 * Metadata describing one container owned by an inventory (section 7.2).
 *
 * NOTE (design deviation from the TЗ sketch): the actual item entries do NOT live
 * inside the container struct. They live in the component's single
 * FReplicatedInventoryList, tagged with this ContainerId. A FastArraySerializer
 * only delta-replicates correctly as a direct UPROPERTY, so nesting one inside a
 * replicated TArray<FInventoryContainer> would silently fall back to full-array
 * replication. Keeping containers as lightweight metadata fixes that (section 32).
 */
USTRUCT(BlueprintType)
struct ITEMINVENTORY_API FInventoryContainer
{
	GENERATED_BODY()

	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Container")
	FGuid ContainerId;

	/** Logical identity, e.g. Container.Backpack / Container.Hotbar / Container.Vehicle.Cargo. */
	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Container")
	FGameplayTag ContainerTag;

	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Container")
	EInventoryContainerType Type = EInventoryContainerType::SlotList;

	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Container")
	int32 Width = 0;

	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Container")
	int32 Height = 0;

	/** Used by SlotList/Equipment/Hotbar; for Grid types capacity is Width*Height. */
	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Container")
	int32 MaxSlots = 0;

	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Container")
	float MaxWeight = 0.f;

	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Container")
	FGameplayTagContainer AcceptedItemTags;

	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Container")
	FGameplayTagContainer BlockedItemTags;

	/** Set when this container lives inside another item (a backpack/pouch item) - section 7. */
	UPROPERTY(BlueprintReadOnly, Category = "Container")
	FGuid OwnerItemInstanceId;

	FInventoryContainer() = default;

	bool IsNested() const { return OwnerItemInstanceId.IsValid(); }

	/** Number of addressable slots in this container (0 = unlimited weight-gated list). */
	int32 GetSlotCount() const
	{
		if (Type == EInventoryContainerType::Grid)
		{
			return FMath::Max(0, Width) * FMath::Max(0, Height);
		}
		return FMath::Max(0, MaxSlots);
	}

	bool HasSlotLimit() const { return GetSlotCount() > 0; }
	bool HasWeightLimit() const { return MaxWeight > 0.f; }
};
