// Fill out your copyright notice in the Description page of Project Settings.


#include "ItemDetailsWidget.h"

#include "Components/Image.h"
#include "Components/ProgressBar.h"
#include "Components/TextBlock.h"
#include "Components/Widget.h"
#include "InventoryComponent.h"
#include "ItemDataAsset.h"

void UItemDetailsWidget::NativeConstruct()
{
	Super::NativeConstruct();

	// Etat vide des la construction : sans ca le panneau afficherait les valeurs
	// placeholder saisies dans la Designer jusqu'au premier survol.
	Clear();
}

void UItemDetailsWidget::NativeDestruct()
{
	BindInventory(nullptr);

	Super::NativeDestruct();
}

void UItemDetailsWidget::BindInventory(UInventoryComponent* InInventory)
{
	if (BoundInventory.Get() == InInventory)
	{
		return;
	}

	if (BoundInventory.IsValid())
	{
		BoundInventory->OnInventoryChanged.RemoveDynamic(this, &UItemDetailsWidget::HandleInventoryChanged);
	}

	BoundInventory = InInventory;

	if (BoundInventory.IsValid())
	{
		BoundInventory->OnInventoryChanged.AddDynamic(this, &UItemDetailsWidget::HandleInventoryChanged);
	}
}

void UItemDetailsWidget::ShowSlot(UInventoryComponent* InInventory, int32 InSlotIndex)
{
	BindInventory(InInventory);
	SlotIndex = InSlotIndex;

	Refresh();
}

void UItemDetailsWidget::Clear()
{
	BindInventory(nullptr);
	SlotIndex = INDEX_NONE;

	Refresh();
}

void UItemDetailsWidget::ClearSlot(const UInventoryComponent* InInventory, int32 InSlotIndex)
{
	if (BoundInventory.Get() == InInventory && SlotIndex == InSlotIndex)
	{
		Clear();
	}
}

void UItemDetailsWidget::HandleInventoryChanged()
{
	// La case survolee a change sous le curseur : une charge consommee, une pile
	// deplacee. On relit plutot que de garder une copie perimee a l'ecran.
	Refresh();
}

void UItemDetailsWidget::Refresh()
{
	// Surtout pas "Slot" : UWidget a deja un membre de ce nom, et le masquer est
	// une erreur de compilation (C4458) traitee comme telle par le moteur.
	const FInventorySlot* HoveredSlot = nullptr;
	if (BoundInventory.IsValid())
	{
		const TArray<FInventorySlot>& Slots = BoundInventory->GetSlots();
		if (Slots.IsValidIndex(SlotIndex) && !Slots[SlotIndex].IsEmpty())
		{
			HoveredSlot = &Slots[SlotIndex];
		}
	}

	if (ContentRoot)
	{
		// Hidden et non Collapsed : le panneau garde sa taille, donc rien ne
		// bouge dans la mise en page quand le curseur quitte une case.
		ContentRoot->SetVisibility(HoveredSlot ? ESlateVisibility::SelfHitTestInvisible : ESlateVisibility::Hidden);
	}

	if (!HoveredSlot)
	{
		ClearDisplay();
		return;
	}

	const UItemDataAsset* Item = HoveredSlot->Item;

	if (ItemIcon)
	{
		if (Item->Icon)
		{
			ItemIcon->SetBrushFromTexture(Item->Icon, /*bMatchSize=*/false);
			ItemIcon->SetVisibility(ESlateVisibility::HitTestInvisible);
		}
		else
		{
			ItemIcon->SetVisibility(ESlateVisibility::Hidden);
		}
	}

	if (ItemNameText)
	{
		ItemNameText->SetText(Item->DisplayName);
	}

	if (ItemDescriptionText)
	{
		ItemDescriptionText->SetText(Item->Description);
	}

	// --- Usure ---
	// Meme regle que sur la case de la grille : rien a montrer sur un objet a
	// usage unique, et le bloc se replie plutot que de laisser un vide.
	const int32 MaxUses = FMath::Max(1, Item->MaxUses);
	const bool bHasUses = MaxUses > 1;

	if (UsesPanel)
	{
		UsesPanel->SetVisibility(bHasUses ? ESlateVisibility::SelfHitTestInvisible : ESlateVisibility::Collapsed);
	}

	if (bHasUses)
	{
		if (UsesBar)
		{
			UsesBar->SetPercent(FMath::Clamp(static_cast<float>(HoveredSlot->RemainingUses) / static_cast<float>(MaxUses), 0.f, 1.f));
		}

		if (UsesText)
		{
			UsesText->SetText(FText::Format(INVTEXT("{0} / {1}"),
				FText::AsNumber(HoveredSlot->RemainingUses), FText::AsNumber(MaxUses)));
		}
	}
}

void UItemDetailsWidget::ClearDisplay()
{
	if (ItemIcon)
	{
		// Hidden et non Collapsed : l'icone garde sa place, donc le nom et la
		// description ne remontent pas d'un cran au moment de disparaitre.
		ItemIcon->SetVisibility(ESlateVisibility::Hidden);
	}

	if (ItemNameText)
	{
		ItemNameText->SetText(FText::GetEmpty());
	}

	if (ItemDescriptionText)
	{
		ItemDescriptionText->SetText(FText::GetEmpty());
	}

	if (UsesPanel)
	{
		UsesPanel->SetVisibility(ESlateVisibility::Collapsed);
	}
}
