// Copyright ExByte Studios. Item Interaction Ecosystem.

#pragma once

#include "CoreMinimal.h"
#include "UObject/Interface.h"
#include "ItemInstanceData.h"
#include "ItemInteractionInterfaces.generated.h"

/**
 * Implemented by world actors that represent a concrete item (e.g. APickupItemActor).
 * Lets the interaction layer read/take the item without ItemInteraction depending on
 * ItemWorld - the dependency only flows World -> Interaction.
 */
UINTERFACE(MinimalAPI, BlueprintType)
class UWorldItemProvider : public UInterface
{
	GENERATED_BODY()
};

class ITEMINTERACTION_API IWorldItemProvider
{
	GENERATED_BODY()

public:
	/** Returns the item this actor carries. */
	virtual bool GetProvidedItem(FItemInstanceData& OutItem) const = 0;

	/** True if the provider is currently locked/claimed by another interaction. */
	virtual bool IsItemAvailable() const { return true; }

	/** Server: the item was taken into an inventory/hands - tear down the world actor. */
	virtual void NotifyItemTaken(AActor* Taker) {}

	/** Server: only part of the stack was taken; write back the remaining item. */
	virtual void UpdateProvidedItem(const FItemInstanceData& RemainingItem) {}

	/** Server: mark this world item as being physically carried by Holder (or released). */
	virtual void SetCarried(AActor* Holder, bool bCarried) {}
};

/**
 * Implemented by whatever tracks the pawn's currently held/carried item
 * (the character or its UHeldItemComponent). The resolver queries it to build
 * "held + target" interactions without depending on ItemWorld.
 */
UINTERFACE(MinimalAPI, BlueprintType)
class UHeldItemInterface : public UInterface
{
	GENERATED_BODY()
};

class ITEMINTERACTION_API IHeldItemInterface
{
	GENERATED_BODY()

public:
	virtual bool GetHeldItem(FItemInstanceData& OutItem) const = 0;
	virtual bool HasHeldItem() const = 0;
};

/**
 * Implemented by world objects that react to a held item being used on them
 * (section 15): pour fuel into a generator, barricade a door, place bait, etc.
 * Found on the target actor or any of its components.
 */
UINTERFACE(MinimalAPI, BlueprintType)
class UItemUseTarget : public UInterface
{
	GENERATED_BODY()
};

class ITEMINTERACTION_API IItemUseTarget
{
	GENERATED_BODY()

public:
	/**
	 * Server: apply the held item to this target for the given result verb (e.g.
	 * "TransferFuel"). May mutate HeldItem (reduce fuel/charge). Returns true if it
	 * did something - the caller then writes HeldItem back to the held component.
	 */
	virtual bool ReceiveHeldUse(FName ResultVerb, FItemInstanceData& HeldItem, AActor* Instigator) = 0;
};
