#pragma once

#include "CoreMinimal.h"
#include "LoadoutViewInterface.h"
#include "CoreBaseUserWidget.h"
#include "LoadoutSlotClickedDelegate.h"
#include "LoadoutInventorySlotClickedDelegate.h"
#include "PaginationAnimationCompletedDelegate.h"
#include "EPlayerRole.h"
#include "Templates/SubclassOf.h"
#include "Layout/Margin.h"
#include "Types/SlateEnums.h"
#include "ELoadoutSlot.h"
#include "ELoadoutInventoryDisabledReason.h"
#include "CoreLoadoutWidget.generated.h"

class UCoreLoadoutItemAndOfferingSectionWidget;
class UCoreLoadoutCharacterClassSectionWidget;
class UCoreLoadoutPerksSectionWidget;
class UCoreLoadoutSkillsSectionWidget;
class UDBDTextBlock;
class UCoreSearchBarWidget;
class UGridPanel;
class UOverlay;
class UCorePaginationContainerWidget;
class UCoreInputSwitcherWidget;
class UCoreMenuLoadoutPartWidget;
class UCoreMenuAddonWidget;
class UCoreMenuPerkWidget;
class UCoreMenuClassWidget;
class UCoreMenuSkillWidget;
class ULoadoutItemViewData;
class UCoreButtonWidget;

UCLASS(Blueprintable, EditInlineNew)
class DBDUIVIEWSCORE_API UCoreLoadoutWidget : public UCoreBaseUserWidget, public ILoadoutViewInterface
{
	GENERATED_BODY()

protected:
	UPROPERTY(EditAnywhere, BlueprintReadWrite, BlueprintCallable)
	FLoadoutSlotClickedDelegate _onLoadoutSlotClicked;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, BlueprintCallable)
	FLoadoutInventorySlotClickedDelegate _onLoadoutInventorySlotClicked;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, BlueprintCallable)
	FPaginationAnimationCompletedDelegate _onPaginationAnimationCompleted;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	int32 _debugLoadoutLayoutMask;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	EPlayerRole _debugPlayerRole;

	UPROPERTY(BlueprintReadWrite, meta=(BindWidgetOptional))
	UCoreLoadoutItemAndOfferingSectionWidget* ItemAndOfferingSection;

	UPROPERTY(BlueprintReadWrite, meta=(BindWidgetOptional))
	UCoreLoadoutCharacterClassSectionWidget* CharacterClassSection;

	UPROPERTY(BlueprintReadWrite, meta=(BindWidgetOptional))
	UCoreLoadoutPerksSectionWidget* PerksSection;

	UPROPERTY(BlueprintReadWrite, meta=(BindWidgetOptional))
	UCoreLoadoutSkillsSectionWidget* SkillsSection;

	UPROPERTY(BlueprintReadWrite, meta=(BindWidgetOptional))
	UDBDTextBlock* InventoryTitleTB;

	UPROPERTY(BlueprintReadWrite, meta=(BindWidgetOptional))
	UDBDTextBlock* InventorySubtitleTB;

	UPROPERTY(BlueprintReadWrite, meta=(BindWidgetOptional))
	UCoreSearchBarWidget* SearchBar;

	UPROPERTY(BlueprintReadWrite, meta=(BindWidgetOptional))
	UGridPanel* InventoryGridContainer;

	UPROPERTY(BlueprintReadWrite, meta=(BindWidgetOptional))
	UOverlay* PaginationOverlay;

	UPROPERTY(BlueprintReadWrite, meta=(BindWidgetOptional))
	UCorePaginationContainerWidget* PaginationGridContainer;

	UPROPERTY(BlueprintReadWrite, meta=(BindWidgetOptional))
	UCoreInputSwitcherWidget* LeftArrow;

	UPROPERTY(BlueprintReadWrite, meta=(BindWidgetOptional))
	UCoreInputSwitcherWidget* RightArrow;

	UPROPERTY(BlueprintReadWrite, meta=(BindWidgetOptional))
	UOverlay* InventoryDisabledOverlay;

	UPROPERTY(BlueprintReadWrite, meta=(BindWidgetOptional))
	UDBDTextBlock* InventoryDisabledTB;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, NoClear)
	TSubclassOf<UCoreMenuLoadoutPartWidget> _loadoutPowerClass;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, NoClear)
	TSubclassOf<UCoreMenuLoadoutPartWidget> _loadoutItemWidgetClass;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, NoClear)
	TSubclassOf<UCoreMenuAddonWidget> _loadoutAddonClass;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, NoClear)
	TSubclassOf<UCoreMenuLoadoutPartWidget> _loadoutOfferingClass;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, NoClear)
	TSubclassOf<UCoreMenuPerkWidget> _loadoutPerkClass;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, NoClear)
	TSubclassOf<UCoreMenuClassWidget> _loadoutCharacterClassClass;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, NoClear)
	TSubclassOf<UCoreMenuSkillWidget> _loadoutSkillClass;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	int32 _inventoryPerRow;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	int32 _inventoryPerColumn;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	int32 _cellsPerRow;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	float _inventorySemiTransparentOpacity;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	FMargin _inventoryItemPadding;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	FMargin _inventoryPerkPadding;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	FMargin _inventoryOfferingPadding;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	FMargin _inventoryCharacterClassesPadding;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	float _inventoryPerkExtraNudge;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	float _inventoryOfferingExtraNudge;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	float _inventoryCharacterClassesExtraNudge;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	bool _stopAnimation;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	TEnumAsByte<EHorizontalAlignment> _inventorySlotHorizontalAlignment;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	TEnumAsByte<EVerticalAlignment> _inventorySlotVerticalAlignment;

private:
	UPROPERTY(BlueprintReadWrite, Transient, Instanced, meta=(AllowPrivateAccess=true))
	TArray<UCoreMenuLoadoutPartWidget*> _inventoryItemWidgetList;

	UPROPERTY(BlueprintReadWrite, Transient, meta=(AllowPrivateAccess=true))
	ELoadoutSlot _loadoutSelectedSlot;

	UPROPERTY(BlueprintReadWrite, Transient, meta=(AllowPrivateAccess=true))
	TArray<ULoadoutItemViewData*> _inventoryViewData;

protected:
	UFUNCTION(BlueprintCallable, BlueprintImplementableEvent)
	void UpdateLoadoutLayout();

private:
	UFUNCTION(BlueprintCallable)
	bool UpdateInventoryStatus(const ELoadoutInventoryDisabledReason inventoryDisabledReason, const int32 numberOfPages);

	UFUNCTION(BlueprintCallable)
	void UpdateInventoryGridContent();

protected:
	UFUNCTION(BlueprintCallable)
	void StopPaginationAnimation(const float inventoryElementsOpacity);

	UFUNCTION(BlueprintCallable, BlueprintImplementableEvent)
	void PlayPaginationOutAnimation(bool isNextPage);

private:
	UFUNCTION(BlueprintCallable)
	void OnSlotClicked(ELoadoutSlot clickedLoadoutSlot);

	UFUNCTION(BlueprintCallable)
	void OnPaginationSelected(const int32 currentPage, bool isUpdate);

	UFUNCTION(BlueprintCallable)
	void OnPaginationAnimationCompleted();

	UFUNCTION(BlueprintCallable)
	void OnInventoryRightArrowClicked();

	UFUNCTION(BlueprintCallable)
	void OnInventoryLeftArrowClicked();

	UFUNCTION(BlueprintCallable)
	void OnInventoryItemUnhovered(UCoreButtonWidget* buttonTarget);

	UFUNCTION(BlueprintCallable)
	void OnInventoryItemHovered(UCoreButtonWidget* buttonTarget);

	UFUNCTION(BlueprintCallable)
	void OnInventoryItemClicked(UCoreButtonWidget* itemWidget);

protected:
	UFUNCTION(BlueprintPure)
	bool IsLayoutSectionEnabled(const int32 loadoutLayoutMask) const;

private:
	UFUNCTION(BlueprintCallable)
	UCoreMenuLoadoutPartWidget* CreateInventoryGrid(int32 index, TSubclassOf<UCoreMenuLoadoutPartWidget> currentLoadoutClass);

public:
	UCoreLoadoutWidget();
};

FORCEINLINE uint32 GetTypeHash(const UCoreLoadoutWidget) { return 0; }
