#pragma once

#include "CoreMinimal.h"
#include "Blueprint/UserWidget.h"

#include "HyperTwistFourDimensionalHUDWidget.generated.h"

class UHorizontalBox;
class UButton;
class UTextBlock;

DECLARE_DYNAMIC_MULTICAST_DELEGATE(FHyperTwistFourDimensionalHudActionSignature);

UCLASS(BlueprintType, Blueprintable)
class UNREALHYPERTWIST_API UHyperTwistFourDimensionalHUDWidget : public UUserWidget
{
	GENERATED_BODY()

public:
	UHyperTwistFourDimensionalHUDWidget(
		const FObjectInitializer& ObjectInitializer);

	UFUNCTION(BlueprintCallable, Category = "HyperTwist|4D|HUD")
	bool PrepareHudSurface();

	UFUNCTION(BlueprintPure, Category = "HyperTwist|4D|HUD")
	bool IsHudSurfaceReady() const;

	UFUNCTION(BlueprintCallable, Category = "HyperTwist|4D|HUD")
	void ConfigureSurface(
		const FString& Title,
		const FString& StateSummary,
		const FString& SelectionSummary,
		const FString& LastAction,
		const FString& PersistenceSummary,
		bool bCellFirstMode
	);

	UPROPERTY(BlueprintAssignable, Category = "HyperTwist|4D|HUD")
	FHyperTwistFourDimensionalHudActionSignature OnCycleAxisRequested;

	UPROPERTY(BlueprintAssignable, Category = "HyperTwist|4D|HUD")
	FHyperTwistFourDimensionalHudActionSignature OnPreviousLayerRequested;

	UPROPERTY(BlueprintAssignable, Category = "HyperTwist|4D|HUD")
	FHyperTwistFourDimensionalHudActionSignature OnNextLayerRequested;

	UPROPERTY(BlueprintAssignable, Category = "HyperTwist|4D|HUD")
	FHyperTwistFourDimensionalHudActionSignature OnPreviousPlaneRequested;

	UPROPERTY(BlueprintAssignable, Category = "HyperTwist|4D|HUD")
	FHyperTwistFourDimensionalHudActionSignature OnNextPlaneRequested;

	UPROPERTY(BlueprintAssignable, Category = "HyperTwist|4D|HUD")
	FHyperTwistFourDimensionalHudActionSignature OnCounterClockwiseRequested;

	UPROPERTY(BlueprintAssignable, Category = "HyperTwist|4D|HUD")
	FHyperTwistFourDimensionalHudActionSignature OnClockwiseRequested;

	UPROPERTY(BlueprintAssignable, Category = "HyperTwist|4D|HUD")
	FHyperTwistFourDimensionalHudActionSignature OnToggleShellRequested;

	UPROPERTY(BlueprintAssignable, Category = "HyperTwist|4D|HUD")
	FHyperTwistFourDimensionalHudActionSignature OnScrambleRequested;

	UPROPERTY(BlueprintAssignable, Category = "HyperTwist|4D|HUD")
	FHyperTwistFourDimensionalHudActionSignature OnResetRequested;

	UPROPERTY(BlueprintAssignable, Category = "HyperTwist|4D|HUD")
	FHyperTwistFourDimensionalHudActionSignature OnSaveRequested;

	UPROPERTY(BlueprintAssignable, Category = "HyperTwist|4D|HUD")
	FHyperTwistFourDimensionalHudActionSignature OnLoadRequested;

protected:
	virtual TSharedRef<SWidget> RebuildWidget() override;

private:
	void EnsureWidgetTreeBuilt();
	UTextBlock* MakeText(
		const FString& Text,
		int32 FontSize,
		const FLinearColor& Color,
		const FName& Name = NAME_None
	);
	UButton* AddButton(
		UHorizontalBox* Parent,
		const FString& Label,
		const FName& Name,
		bool bPrimary = false
	);

	UFUNCTION()
	void HandleCycleAxis();

	UFUNCTION()
	void HandlePreviousLayer();

	UFUNCTION()
	void HandleNextLayer();

	UFUNCTION()
	void HandlePreviousPlane();

	UFUNCTION()
	void HandleNextPlane();

	UFUNCTION()
	void HandleCounterClockwise();

	UFUNCTION()
	void HandleClockwise();

	UFUNCTION()
	void HandleToggleShell();

	UFUNCTION()
	void HandleScramble();

	UFUNCTION()
	void HandleReset();

	UFUNCTION()
	void HandleSave();

	UFUNCTION()
	void HandleLoad();

	UPROPERTY(Transient)
	TObjectPtr<UTextBlock> TitleText = nullptr;

	UPROPERTY(Transient)
	TObjectPtr<UTextBlock> StateText = nullptr;

	UPROPERTY(Transient)
	TObjectPtr<UTextBlock> SelectionText = nullptr;

	UPROPERTY(Transient)
	TObjectPtr<UTextBlock> LastActionText = nullptr;

	UPROPERTY(Transient)
	TObjectPtr<UTextBlock> PersistenceText = nullptr;

	UPROPERTY(Transient)
	TObjectPtr<UTextBlock> GuidanceText = nullptr;

	UPROPERTY(Transient)
	TObjectPtr<UHorizontalBox> SelectionActionRow = nullptr;

	UPROPERTY(Transient)
	TObjectPtr<UHorizontalBox> TurnActionRow = nullptr;

	UPROPERTY(Transient)
	TObjectPtr<UHorizontalBox> ScrambleActionRow = nullptr;

	UPROPERTY(Transient)
	TObjectPtr<UButton> ShellButton = nullptr;
};
