#pragma once

#include "CoreMinimal.h"
#include "UObject/Object.h"
#include "ItemInstance.generated.h"

class UItemDefinition;
struct FItemSaveRecord;
struct FInstancedStruct;

/**
 * Base for per-instance mutable state carried inside FItemSaveRecord::State.
 * Subclass per item type (see FClothingInstanceState, FSexToyInstanceState).
 */
USTRUCT()
struct NAKEDDESIRE_API FItemInstanceState
{
	GENERATED_BODY()
};

UCLASS(Abstract)
class NAKEDDESIRE_API UItemInstance : public UObject
{
	GENERATED_BODY()

public:
	virtual void PostInitProperties() override;
	virtual void PostDuplicate(EDuplicateMode::Type DuplicateMode) override;

	FGuid GetInstanceId() const { return InstanceId; }
	void SetInstanceId(FGuid InId);

	UItemDefinition* GetItemDefinition() const { return ItemDefinition; }
	void SetItemDefinition(UItemDefinition* InDefinition) { ItemDefinition = InDefinition; }

	/** Serialize identity + definition + per-type state into a record. */
	FItemSaveRecord ToSaveRecord() const;

	/**
	 * Reconstruct the correct UItemInstance subclass from a saved record,
	 * driven by the definition's GetInstanceClass(). Returns nullptr if the
	 * definition fails to load.
	 */
	static UItemInstance* CreateFromRecord(UObject* Outer, const FItemSaveRecord& Record);

protected:
	/** Override to pack this type's mutable state into OutState. */
	virtual void CaptureState(FInstancedStruct& OutState) const {}

	/** Override to restore this type's mutable state from InState. */
	virtual void ApplyState(const FInstancedStruct& InState) {}

	UPROPERTY(VisibleAnywhere, SaveGame, BlueprintReadOnly, Category = "Item", meta = (AllowPrivateAccess = "true"))
	FGuid InstanceId;

	UPROPERTY()
	TObjectPtr<UItemDefinition> ItemDefinition;
};