// Copyright ExByte Studios. Item Interaction Ecosystem.

#pragma once

#include "CoreMinimal.h"
#include "UObject/Object.h"
#include "GameplayTagContainer.h"
#include "ItemEnums.h"
#include "InteractionTypes.h"
#include "InteractionAction.generated.h"

/**
 * A single interaction verb, authored as an instanced object on an
 * InteractableComponent (section 16). This is the Blueprint-extensible path:
 * built-in modes are also handled directly by the interaction component, but
 * any custom verb can be added here without C++.
 *
 * CanExecute/Execute must be safe to run on the server. CanExecute may also run
 * on the client for predictive UI, so it must not mutate state.
 */
UCLASS(Abstract, Blueprintable, EditInlineNew, DefaultToInstanced, CollapseCategories)
class ITEMINTERACTION_API UInteractionAction : public UObject
{
	GENERATED_BODY()

public:
	UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Action")
	FGameplayTag ActionTag;

	UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Action")
	FText DisplayText;

	UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Action")
	EItemInteractionMode Mode = EItemInteractionMode::Use;

	UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Action")
	int32 Priority = 300;

	UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Action")
	bool bRequiresHold = false;

	UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Action")
	float HoldDuration = 0.f;

	UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Action")
	FInteractionExecutionData Execution;

	UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Action")
	TArray<FInteractionRequirement> Requirements;

	/** Pure check: are all requirements satisfied? Writes the first failure reason. */
	UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "Action")
	bool CanExecute(const FInteractionContext& Context, FText& OutDisabledReason) const;
	virtual bool CanExecute_Implementation(const FInteractionContext& Context, FText& OutDisabledReason) const;

	/** Server-authoritative effect. */
	UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "Action")
	void Execute(const FInteractionContext& Context);
	virtual void Execute_Implementation(const FInteractionContext& Context);

	/** Turns this action into a UI option for the given context. */
	FInteractionOption BuildOption(const FInteractionContext& Context) const;

	virtual UWorld* GetWorld() const override;
};
