#pragma once

#include "CoreMinimal.h"
#include "Kismet/BlueprintFunctionLibrary.h"
#include "HyperTwistTraining/HyperTwistTrainingTypes.h"
#include "HyperTwistXrRuntimeLibrary.generated.h"

UENUM(BlueprintType)
enum class EHyperTwistXrDominantHand : uint8
{
	Right UMETA(DisplayName = "Right"),
	Left UMETA(DisplayName = "Left")
};

UENUM(BlueprintType)
enum class EHyperTwistXrPostureMode : uint8
{
	Standing UMETA(DisplayName = "Standing"),
	Seated UMETA(DisplayName = "Seated"),
	Hybrid UMETA(DisplayName = "Hybrid")
};

USTRUCT(BlueprintType)
struct FHyperTwistXrPreferenceProfile
{
	GENERATED_BODY()

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	FString ProfileId;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	FString Title;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	FString Summary;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	EHyperTwistXrDominantHand DominantHand = EHyperTwistXrDominantHand::Right;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	EHyperTwistXrPostureMode PostureMode = EHyperTwistXrPostureMode::Standing;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	float MoveSpeedUnitsPerSecond = 220.0f;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	float VerticalAdjustmentUnitsPerSecond = 120.0f;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	float SnapTurnDegrees = 30.0f;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	float SnapTurnAxisThreshold = 0.65f;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	float SnapTurnResetThreshold = 0.25f;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	float SmoothTurnDegreesPerSecond = 90.0f;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	float PointerLengthUnits = 180.0f;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	float WorldToMetersScale = 100.0f;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	float ComfortVignetteStrength = 0.35f;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	float ControllerDeadZone = 0.15f;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	bool bSmoothLocomotionEnabled = true;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	bool bSnapTurnEnabled = true;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	bool bSmoothTurnFallbackEnabled = false;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	bool bAllowVerticalAdjustment = true;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	bool bMirrorSpectatorView = true;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	bool bHapticsEnabled = true;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	TArray<FString> PreferenceFieldTags;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	TArray<FString> ComfortSurfaceTags;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	TArray<FString> ExplicitExclusions;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	FHyperTwistTrainingSourceAttribution SourceAttribution;

	bool IsStructurallyValid() const
	{
		return !ProfileId.IsEmpty()
			&& !Title.IsEmpty()
			&& SourceAttribution.IsStructurallyValid();
	}
};

USTRUCT(BlueprintType)
struct FHyperTwistXrControllerBindingProfile
{
	GENERATED_BODY()

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	FString ProfileId;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	FString Title;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	FString Summary;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	TArray<FString> RequiredAxisNames;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	TArray<FString> ControllerFamilyIds;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	TArray<FString> InteractionSurfaceTags;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	TArray<FString> ExplicitExclusions;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	FHyperTwistTrainingSourceAttribution SourceAttribution;

	bool IsStructurallyValid() const
	{
		return !ProfileId.IsEmpty()
			&& !Title.IsEmpty()
			&& RequiredAxisNames.Num() > 0
			&& SourceAttribution.IsStructurallyValid();
	}
};

USTRUCT(BlueprintType)
struct FHyperTwistXrControllerSettingsOwnershipSurface
{
	GENERATED_BODY()

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	FString SettingsOwnerId;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	FString RebindingSurfaceId;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	FString Title;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	FString Summary;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	FString DefaultLayoutPresetId;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	TArray<FString> UserVisibleSettingFieldTags;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	TArray<FString> RebindableInputNames;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	TArray<FString> LayoutPresetIds;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	TArray<FString> SupportedControllerFamilies;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	TArray<FString> ExplicitExclusions;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	FHyperTwistTrainingSourceAttribution SourceAttribution;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	bool bUserFacingSettingsReady = true;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	bool bUserFacingRebindingReady = true;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	bool bWindowsPackagedControllerProofReady = false;

	bool IsStructurallyValid() const
	{
		return !SettingsOwnerId.IsEmpty()
			&& !RebindingSurfaceId.IsEmpty()
			&& !Title.IsEmpty()
			&& !DefaultLayoutPresetId.IsEmpty()
			&& UserVisibleSettingFieldTags.Num() > 0
			&& RebindableInputNames.Num() > 0
			&& LayoutPresetIds.Num() > 0
			&& SupportedControllerFamilies.Num() > 0
			&& SourceAttribution.IsStructurallyValid();
	}
};

USTRUCT(BlueprintType)
struct FHyperTwistXrRuntimeOwnershipSurface
{
	GENERATED_BODY()

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	FString RuntimeOwnerId;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	FString Title;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	FString Summary;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	FString PreferenceProfileId;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	FString ControllerBindingProfileId;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	FString WorldAnchorContractId;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	FString LeftMotionSourceId;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	FString RightMotionSourceId;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	TArray<FString> RequiredPackageIds;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	TArray<FString> RequiredSurfaceTags;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	TArray<FString> SupportedControllerFamilies;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	TArray<FString> ExplicitExclusions;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	FHyperTwistTrainingSourceAttribution SourceAttribution;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	bool bOpenXrPluginRequired = true;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	bool bMotionControllerComponentsRequired = true;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	bool bDesktopFallbackAllowed = true;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	bool bComfortProfileReady = true;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	bool bControllerBindingsReady = true;

	bool IsStructurallyValid() const
	{
		return !RuntimeOwnerId.IsEmpty()
			&& !Title.IsEmpty()
			&& !PreferenceProfileId.IsEmpty()
			&& !ControllerBindingProfileId.IsEmpty()
			&& !LeftMotionSourceId.IsEmpty()
			&& !RightMotionSourceId.IsEmpty()
			&& SourceAttribution.IsStructurallyValid();
	}
};

UCLASS(BlueprintType)
class UNREALHYPERTWIST_API UHyperTwistXrRuntimeLibrary : public UBlueprintFunctionLibrary
{
	GENERATED_BODY()

public:
	UFUNCTION(BlueprintPure, Category = "HyperTwist|XR")
	static FHyperTwistXrPreferenceProfile GetDefaultXrPreferenceProfile();

	UFUNCTION(BlueprintPure, Category = "HyperTwist|XR")
	static FHyperTwistXrControllerBindingProfile GetDefaultXrControllerBindingProfile();

	UFUNCTION(BlueprintPure, Category = "HyperTwist|XR")
	static FHyperTwistXrControllerSettingsOwnershipSurface
	BuildBundledXrControllerSettingsOwnershipSurface();

	UFUNCTION(BlueprintPure, Category = "HyperTwist|XR")
	static FHyperTwistXrRuntimeOwnershipSurface BuildBundledXrRuntimeOwnershipSurface();
};
