#pragma once

#include "CoreMinimal.h"
#include "Kismet/BlueprintFunctionLibrary.h"

#include "HyperTwistFirstRunLaunchLibrary.generated.h"

enum class EHyperTwistPackagedStartupRouteParseResult : uint8
{
	NotPresent,
	Valid,
	Invalid
};

UENUM(BlueprintType)
enum class EHyperTwistPuzzleAvailability : uint8
{
	Playable,
	BrowserPreview,
	LearningLibrary,
	Planned
};

UENUM(BlueprintType)
enum class EHyperTwistIntegrationLicenseLane : uint8
{
	Permissive,
	RestrictiveCleanRoom,
	BoundarySensitive
};

UENUM(BlueprintType)
enum class EHyperTwistIntegrationSurface : uint8
{
	NativePlayable,
	NativePlayerService,
	BrowserSupport,
	OperatorSupport
};

USTRUCT(BlueprintType)
struct UNREALHYPERTWIST_API FHyperTwistIntegratedCapability
{
	GENERATED_BODY()

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist|Integration")
	FString CapabilityId;

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

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

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist|Integration")
	FString CanonicalRepository;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist|Integration")
	FString LicenseId;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist|Integration")
	EHyperTwistIntegrationLicenseLane LicenseLane =
		EHyperTwistIntegrationLicenseLane::Permissive;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist|Integration")
	EHyperTwistIntegrationSurface Surface =
		EHyperTwistIntegrationSurface::NativePlayerService;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist|Integration")
	FString PrimaryExperienceRoute;

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

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist|Integration")
	FString ImplementationPosture;

	bool IsStructurallyValid() const
	{
		return !CapabilityId.IsEmpty()
			&& !Title.IsEmpty()
			&& !Summary.IsEmpty()
			&& !CanonicalRepository.IsEmpty()
			&& !LicenseId.IsEmpty()
			&& !PrimaryExperienceRoute.IsEmpty()
			&& !RuntimeOwnerId.IsEmpty()
			&& !ImplementationPosture.IsEmpty()
			&& (LicenseLane != EHyperTwistIntegrationLicenseLane::RestrictiveCleanRoom
				|| ImplementationPosture.Contains(TEXT("clean-room")));
	}
};

USTRUCT(BlueprintType)
struct UNREALHYPERTWIST_API FHyperTwistFirstRunLaunchRoute
{
	GENERATED_BODY()

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist|FirstRun")
	FString RouteId;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist|FirstRun")
	FString Label;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist|FirstRun")
	FString Description;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist|FirstRun")
	FString MapAssetPath;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist|FirstRun")
	FString LaunchUrl;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist|FirstRun")
	FString GameModeClassPath;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist|FirstRun")
	FString PrimaryInputMode;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist|FirstRun")
	FString RuntimeProofStatus;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist|FirstRun")
	FString PlayerSection;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist|FirstRun")
	FString AvailabilityLabel;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist|FirstRun")
	bool bDefaultSafeChoice = false;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist|FirstRun")
	bool bOpensDashboard = false;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist|FirstRun")
	bool bLaunchesDedicatedMap = false;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist|FirstRun")
	bool bRequiresEntitlement = false;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist|FirstRun")
	bool bRequiresLiveHeadset = false;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist|FirstRun")
	bool bRequiresLiveControllerObservation = false;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist|FirstRun")
	bool bHasWebSimulatorEquivalent = false;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist|FirstRun")
	bool bPlayerFacing = true;

	bool IsStructurallyValid() const;
};

USTRUCT(BlueprintType)
struct UNREALHYPERTWIST_API FHyperTwistPuzzleCatalogEntry
{
	GENERATED_BODY()

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist|Catalog")
	FString PuzzleId;

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

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist|Catalog")
	FString Dimensionality;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist|Catalog")
	FString Description;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist|Catalog")
	EHyperTwistPuzzleAvailability Availability = EHyperTwistPuzzleAvailability::Planned;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist|Catalog")
	FString AvailabilityLabel;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist|Catalog")
	FString LaunchRouteId;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist|Catalog")
	TArray<FString> ExperienceTags;

	bool IsStructurallyValid() const
	{
		return !PuzzleId.IsEmpty()
			&& !Title.IsEmpty()
			&& !Dimensionality.IsEmpty()
			&& !Description.IsEmpty()
			&& !AvailabilityLabel.IsEmpty()
			&& (Availability != EHyperTwistPuzzleAvailability::Playable
				|| !LaunchRouteId.IsEmpty());
	}
};

UCLASS()
class UNREALHYPERTWIST_API UHyperTwistFirstRunLaunchLibrary
	: public UBlueprintFunctionLibrary
{
	GENERATED_BODY()

public:
	UFUNCTION(BlueprintPure, Category = "HyperTwist|FirstRun")
	static FString GetFirstRunLaunchSurfaceId();

	UFUNCTION(BlueprintPure, Category = "HyperTwist|FirstRun")
	static FString GetFirstRunGameModeClassPath();

	UFUNCTION(BlueprintPure, Category = "HyperTwist|FirstRun")
	static FString GetDefaultRouteId();

	UFUNCTION(BlueprintPure, Category = "HyperTwist|FirstRun")
	static FString GetStartupFallbackRouteId();

	UFUNCTION(BlueprintPure, Category = "HyperTwist|FirstRun")
	static FString GetPackagedStartupMapAssetPath();

	UFUNCTION(BlueprintPure, Category = "HyperTwist|FirstRun")
	static FString GetPackagedStartupRouteArgumentName();

	UFUNCTION(BlueprintPure, Category = "HyperTwist|FirstRun")
	static FString GetRuntimeLogFileName();

	UFUNCTION(BlueprintPure, Category = "HyperTwist|FirstRun")
	static FString GetStartupDiagnosticsLogFileName();

	UFUNCTION(BlueprintPure, Category = "HyperTwist|FirstRun")
	static TArray<FString> BuildFirstRunGuidanceLines();

	UFUNCTION(BlueprintPure, Category = "HyperTwist|FirstRun")
	static TArray<FHyperTwistFirstRunLaunchRoute> BuildFirstRunLaunchRoutes();

	UFUNCTION(BlueprintPure, Category = "HyperTwist|FirstRun")
	static TArray<FHyperTwistPuzzleCatalogEntry> BuildPlayerPuzzleCatalog();

	UFUNCTION(BlueprintPure, Category = "HyperTwist|Integration")
	static TArray<FHyperTwistIntegratedCapability> BuildIntegratedCapabilityCatalog();

	UFUNCTION(BlueprintPure, Category = "HyperTwist|Integration")
	static bool TryFindIntegratedCapability(
		const FString& CanonicalRepository,
		FHyperTwistIntegratedCapability& OutCapability
	);

	UFUNCTION(BlueprintPure, Category = "HyperTwist|Integration")
	static FString GetIntegrationLicenseLaneLabel(
		EHyperTwistIntegrationLicenseLane LicenseLane
	);

	UFUNCTION(BlueprintPure, Category = "HyperTwist|Integration")
	static FString GetIntegrationSurfaceLabel(
		EHyperTwistIntegrationSurface Surface
	);

	UFUNCTION(BlueprintPure, Category = "HyperTwist|FirstRun")
	static bool TryFindPuzzleCatalogEntry(
		const FString& PuzzleId,
		FHyperTwistPuzzleCatalogEntry& OutEntry
	);

	UFUNCTION(BlueprintPure, Category = "HyperTwist|FirstRun")
	static bool TryFindFirstRunLaunchRoute(
		const FString& RouteId,
		FHyperTwistFirstRunLaunchRoute& OutRoute
	);

	static EHyperTwistPackagedStartupRouteParseResult ParsePackagedStartupRouteArgument(
		const TCHAR* CommandLine,
		FHyperTwistFirstRunLaunchRoute& OutRoute,
		FString& OutFailureReason
	);
};
