#pragma once

#include "CoreMinimal.h"
#include "HyperTwistUX/HyperTwistPlayerControllerBase.h"
#include "HyperTwistSimulation/HyperTwistVirtual3333ProjectionLibrary.h"
#include "HyperTwistVirtual3333ProjectionPlayerController.generated.h"

class AHyperTwistVirtual3333ProjectionActor;
class UHyperTwistFourDimensionalHUDWidget;

UCLASS(BlueprintType, Blueprintable)
class UNREALHYPERTWIST_API AHyperTwistVirtual3333ProjectionPlayerController
	: public AHyperTwistPlayerControllerBase
{
	GENERATED_BODY()

public:
	AHyperTwistVirtual3333ProjectionPlayerController();

	virtual void BeginPlay() override;
	virtual void SetupInputComponent() override;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist|Virtual3333|Input")
	bool bUseGameAndUiInputMode = true;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist|Virtual3333|Input")
	int32 ScrambleMoveCount = 40;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist|Virtual3333|Input")
	int32 NextScrambleSeed = 2027;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist|Virtual3333|HUD")
	bool bShowPuzzleHud = true;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist|Virtual3333|HUD")
	int32 PuzzleHudZOrder = 120;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist|Virtual3333|HUD")
	TSubclassOf<UHyperTwistFourDimensionalHUDWidget> PuzzleHudWidgetClass;

	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "HyperTwist|Virtual3333|HUD")
	TObjectPtr<UHyperTwistFourDimensionalHUDWidget> ActivePuzzleHudWidget = nullptr;

	UFUNCTION(BlueprintCallable, Category = "HyperTwist|Virtual3333|Input")
	void ResetProjectionToSolved();

	UFUNCTION(BlueprintCallable, Category = "HyperTwist|Virtual3333|Input")
	bool ApplySelectionClockwise();

	UFUNCTION(BlueprintCallable, Category = "HyperTwist|Virtual3333|Input")
	bool ApplySelectionCounterClockwise();

	UFUNCTION(BlueprintCallable, Category = "HyperTwist|Virtual3333|Input")
	bool SetSliceAxis(EHyperTwistVirtual3333Axis SliceAxis);

	UFUNCTION(BlueprintCallable, Category = "HyperTwist|Virtual3333|Input")
	bool SetSliceCoordinate(int32 SliceCoordinate);

	UFUNCTION(BlueprintCallable, Category = "HyperTwist|Virtual3333|Input")
	bool SetSliceLayer(int32 OneBasedLayer);

	UFUNCTION(BlueprintCallable, Category = "HyperTwist|Virtual3333|Input")
	bool CycleSliceLayer(int32 DirectionStep = 1);

	UFUNCTION(BlueprintCallable, Category = "HyperTwist|Virtual3333|Input")
	bool CycleRotationAxis(int32 DirectionStep = 1);

	UFUNCTION(BlueprintCallable, Category = "HyperTwist|Virtual3333|Input")
	void ToggleCellShellRendering();

protected:
	virtual FString GetPauseMenuTitle() const override;
	virtual FString GetPauseMenuSubtitle() const override;
	void ApplyInputMode();
	bool ShowPuzzleHud();
	void RefreshPuzzleHud();
	AHyperTwistVirtual3333ProjectionActor* ResolveProjectionActor() const;
	void HandleSliceAxisX();
	void HandleSliceAxisY();
	void HandleSliceAxisZ();
	void HandleSliceAxisW();
	void HandleSliceCoordinateNegative();
	void HandleSliceCoordinateMiddle();
	void HandleSliceCoordinatePositive();
	void HandleSliceLayerFour();
	void HandleSliceLayerFive();
	void HandleSliceLayerSix();
	void HandlePreviousSliceLayer();
	void HandleNextSliceLayer();
	void HandleCycleRotationAxisBackward();
	void HandleCycleRotationAxisForward();
	void HandleApplyCounterClockwise();
	void HandleApplyClockwise();
	void HandleResetShortcut();
	void HandleScrambleShortcut();
	void HandleToggleShellShortcut();
	void HandleSaveShortcut();
	void HandleLoadShortcut();

	UFUNCTION()
	void HandleHudCycleAxis();

	UFUNCTION()
	void HandleHudPreviousLayer();

	UFUNCTION()
	void HandleHudNextLayer();

	UFUNCTION()
	void HandleHudPreviousPlane();

	UFUNCTION()
	void HandleHudNextPlane();

	UFUNCTION()
	void HandleHudCounterClockwise();

	UFUNCTION()
	void HandleHudClockwise();

	UFUNCTION()
	void HandleHudToggleShell();

	UFUNCTION()
	void HandleHudScramble();

	UFUNCTION()
	void HandleHudReset();

	UFUNCTION()
	void HandleHudSave();

	UFUNCTION()
	void HandleHudLoad();
};
