#include "InventoryScreenWidget.h"

#include "Components/Button.h"
#include "Components/CanvasPanel.h"
#include "Components/CanvasPanelSlot.h"
#include "Equipment/EquipmentPanelWidget.h"
#include "Equipment/EquipmentSlotMenuWidget.h"
#include "Equipment/EquipmentSlotWidget.h"
#include "NakedDesire/Global/PlayerPreviewCaptureSubsystem.h"

void UInventoryScreenWidget::NativeOnActivated()
{
	Super::NativeOnActivated();

	if (!EquipmentSlotMenuWidget && EquipmentSlotMenuWidgetClass)
	{
		// Place the dynamic menu in the same canvas that hosts the blocker.
		// The blocker must live in a UCanvasPanel that spans the area where
		// outside clicks should be captured (typically the screen root canvas).
		if (UCanvasPanel* MenuCanvas = Cast<UCanvasPanel>(MenuBlocker->GetParent()))
		{
			EquipmentSlotMenuWidget = CreateWidget<UEquipmentSlotMenuWidget>(this, EquipmentSlotMenuWidgetClass);
			if (UCanvasPanelSlot* CanvasSlot = Cast<UCanvasPanelSlot>(MenuCanvas->AddChild(EquipmentSlotMenuWidget)))
			{
				CanvasSlot->SetAutoSize(true);
				CanvasSlot->SetAnchors(FAnchors(0.f, 0.f));
				// Render above the blocker so menu clicks aren't eaten by it.
				CanvasSlot->SetZOrder(1);
			}

			EquipmentSlotMenuWidget->OnActionPerformed.AddUObject(this, &UInventoryScreenWidget::CloseMenu);
		}

		EquipmentPanelWidget->OnSlotClicked.BindUObject(this, &UInventoryScreenWidget::HandleSlotClicked);
		MenuBlocker->OnClicked.AddUniqueDynamic(this, &UInventoryScreenWidget::CloseMenu);
	}

	CloseMenu();

	// Spin up the impostor scene-capture preview only while this screen is open.
	if (UPlayerPreviewCaptureSubsystem* Preview = GetWorld()->GetSubsystem<UPlayerPreviewCaptureSubsystem>())
	{
		Preview->SetPreviewActive(true);
	}
}

void UInventoryScreenWidget::NativeOnDeactivated()
{
	Super::NativeOnDeactivated();

	if (UPlayerPreviewCaptureSubsystem* Preview = GetWorld()->GetSubsystem<UPlayerPreviewCaptureSubsystem>())
	{
		Preview->SetPreviewActive(false);
	}
}

void UInventoryScreenWidget::HandleSlotClicked(UEquipmentSlotWidget* SlotWidget)
{
	if (!EquipmentSlotMenuWidget || !SlotWidget)
	{
		return;
	}

	const bool bMenuOpen = EquipmentSlotMenuWidget->GetVisibility() != ESlateVisibility::Collapsed;
	if (bMenuOpen && EquipmentSlotMenuWidget->GetSlotType() == SlotWidget->GetSlotType())
	{
		CloseMenu();
		return;
	}

	EquipmentSlotMenuWidget->Init(SlotWidget->GetSlotType());

	if (UCanvasPanelSlot* MenuSlot = Cast<UCanvasPanelSlot>(EquipmentSlotMenuWidget->Slot))
	{
		if (UCanvasPanel* MenuCanvas = Cast<UCanvasPanel>(MenuBlocker->GetParent()))
		{
			const FGeometry& SlotGeom = SlotWidget->GetCachedGeometry();
			const FVector2D AbsPos = SlotGeom.GetAbsolutePosition() + FVector2D(SlotGeom.GetAbsoluteSize().X, 0.f);
			MenuSlot->SetPosition(MenuCanvas->GetCachedGeometry().AbsoluteToLocal(AbsPos));
		}
	}

	MenuBlocker->SetVisibility(ESlateVisibility::Visible);
	EquipmentSlotMenuWidget->SetVisibility(ESlateVisibility::Visible);
}

void UInventoryScreenWidget::CloseMenu()
{
	if (EquipmentSlotMenuWidget)
	{
		EquipmentSlotMenuWidget->SetVisibility(ESlateVisibility::Collapsed);
	}
	if (MenuBlocker)
	{
		MenuBlocker->SetVisibility(ESlateVisibility::Collapsed);
	}
}