// Copyright Pacificao. All Rights Reserved.

#pragma once

#include "CoreMinimal.h"
#include "Components/ActorComponent.h"
#include "AgrarianTypes.h"
#include "AgrarianInventoryComponent.generated.h"

DECLARE_DYNAMIC_MULTICAST_DELEGATE(FAgrarianInventoryChangedSignature);

UCLASS(ClassGroup = (Agrarian), BlueprintType, Blueprintable, meta = (BlueprintSpawnableComponent))
class UAgrarianInventoryComponent : public UActorComponent
{
	GENERATED_BODY()

public:
	UAgrarianInventoryComponent();

	virtual void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const override;

	UPROPERTY(BlueprintAssignable, Category = "Agrarian|Inventory")
	FAgrarianInventoryChangedSignature OnInventoryChanged;

	UPROPERTY(EditAnywhere, BlueprintReadOnly, ReplicatedUsing = OnRep_Items, Category = "Agrarian|Inventory")
	TArray<FAgrarianItemStack> Items;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Agrarian|Inventory", meta = (ClampMin = "1"))
	int32 MaxSlots = 24;

	UFUNCTION(BlueprintCallable, Category = "Agrarian|Inventory")
	bool HasItem(FName ItemId, int32 Quantity) const;

	UFUNCTION(BlueprintCallable, Category = "Agrarian|Inventory")
	int32 GetItemCount(FName ItemId) const;

	UFUNCTION(BlueprintCallable, Category = "Agrarian|Inventory")
	float GetTotalWeight() const;

	UFUNCTION(BlueprintCallable, Category = "Agrarian|Inventory")
	bool AddItem(const FAgrarianItemStack& Stack);

	UFUNCTION(BlueprintCallable, Category = "Agrarian|Inventory")
	bool RemoveItem(FName ItemId, int32 Quantity);

	UFUNCTION(BlueprintCallable, Category = "Agrarian|Inventory")
	bool ExtractItem(FName ItemId, int32 Quantity, FAgrarianItemStack& OutStack);

	UFUNCTION(BlueprintCallable, Category = "Agrarian|Inventory")
	bool SplitStackByIndex(int32 StackIndex, int32 SplitQuantity);

	UFUNCTION(BlueprintCallable, Category = "Agrarian|Inventory")
	void RestoreSavedItems(const TArray<FAgrarianItemStack>& SavedItems);

	UFUNCTION(Server, Reliable, BlueprintCallable, Category = "Agrarian|Inventory")
	void ServerAddItem(const FAgrarianItemStack& Stack);

	UFUNCTION(Server, Reliable, BlueprintCallable, Category = "Agrarian|Inventory")
	void ServerRemoveItem(FName ItemId, int32 Quantity);

	UFUNCTION(Server, Reliable, BlueprintCallable, Category = "Agrarian|Inventory")
	void ServerSplitStackByIndex(int32 StackIndex, int32 SplitQuantity);

protected:
	UFUNCTION()
	void OnRep_Items();

	void BroadcastInventoryChanged();
};
