#pragma once

#include "CoreMinimal.h"
#include "HyperTwistCore/HyperTwistCoreTypes.h"
#include "HyperTwistTrainingCatalogImportTypes.generated.h"

USTRUCT(BlueprintType)
struct FHyperTwistTrainingCatalogImportedSourceAttribution
{
	GENERATED_BODY()

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

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

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

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

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

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

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

	bool IsStructurallyValid() const
	{
		return !SourceMode.IsEmpty();
	}
};

USTRUCT(BlueprintType)
struct FHyperTwistTrainingCatalogImportedTrackManifest
{
	GENERATED_BODY()

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

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

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

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

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

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

USTRUCT(BlueprintType)
struct FHyperTwistTrainingCatalogImportedContentPackManifest
{
	GENERATED_BODY()

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

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

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

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

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

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	TArray<FHyperTwistTrainingCatalogImportedTrackManifest> TrackManifests;

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

	bool IsStructurallyValid() const
	{
		return !ContentPackId.IsEmpty() && !Title.IsEmpty() && !PuzzleFamily.IsEmpty();
	}
};

USTRUCT(BlueprintType)
struct FHyperTwistTrainingCatalogContentPackManifestDocument
{
	GENERATED_BODY()

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

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	TArray<FHyperTwistTrainingCatalogImportedContentPackManifest> content_packs;

	bool IsStructurallyValid() const
	{
		return !generated_at.IsEmpty() && content_packs.Num() > 0;
	}
};

USTRUCT(BlueprintType)
struct FHyperTwistTrainingCatalogDeckImportSpec
{
	GENERATED_BODY()

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	bool IsStructurallyValid() const
	{
		return !DeckImportSpecId.IsEmpty()
			&& !DeckId.IsEmpty()
			&& !Title.IsEmpty()
			&& !PromptKind.IsEmpty()
			&& !CaseBundleId.IsEmpty();
	}
};

USTRUCT(BlueprintType)
struct FHyperTwistTrainingCatalogDeckImportSpecDocument
{
	GENERATED_BODY()

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

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	TArray<FHyperTwistTrainingCatalogDeckImportSpec> deck_import_specs;

	bool IsStructurallyValid() const
	{
		return !generated_at.IsEmpty() && deck_import_specs.Num() > 0;
	}
};

USTRUCT(BlueprintType)
struct FHyperTwistTrainingCatalogRuntimeBundleMatchFilter
{
	GENERATED_BODY()

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

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

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

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

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

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

	bool IsStructurallyValid() const
	{
		return !source.IsEmpty() && !source_scope.IsEmpty() && !structure_template.IsEmpty();
	}
};

USTRUCT(BlueprintType)
struct FHyperTwistTrainingCatalogRuntimeBundleRetainedCounts
{
	GENERATED_BODY()

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	int32 record_count = 0;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	int32 case_count = 0;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	int32 selector_count = 0;

	bool IsStructurallyValid() const
	{
		return record_count >= 0 && case_count >= 0 && selector_count >= 0;
	}
};

USTRUCT(BlueprintType)
struct FHyperTwistTrainingCatalogRuntimeContentBundle
{
	GENERATED_BODY()

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

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

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

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	FHyperTwistTrainingCatalogRuntimeBundleMatchFilter MatchFilter;

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

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	FHyperTwistTrainingCatalogRuntimeBundleRetainedCounts RetainedCounts;

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

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

	bool IsStructurallyValid() const
	{
		return !CaseBundleId.IsEmpty()
			&& !BundleKind.IsEmpty()
			&& !ContentSourceFile.IsEmpty()
			&& MatchFilter.IsStructurallyValid();
	}
};

USTRUCT(BlueprintType)
struct FHyperTwistTrainingCatalogRuntimeContentBundleDocument
{
	GENERATED_BODY()

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

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	TArray<FHyperTwistTrainingCatalogRuntimeContentBundle> runtime_content_bundles;

	bool IsStructurallyValid() const
	{
		return !generated_at.IsEmpty() && runtime_content_bundles.Num() > 0;
	}
};

USTRUCT(BlueprintType)
struct FHyperTwistTrainingCatalogRawAlgorithmVariant
{
	GENERATED_BODY()

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	int32 variant_index = 0;

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

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

	bool IsStructurallyValid() const
	{
		return variant_index >= 0 && !algorithm.IsEmpty();
	}
};

USTRUCT(BlueprintType)
struct FHyperTwistTrainingCatalogGenerativeSelectorRecord
{
	GENERATED_BODY()

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

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

	bool IsStructurallyValid() const
	{
		return !label.IsEmpty() && !options.IsEmpty();
	}
};

USTRUCT(BlueprintType)
struct FHyperTwistTrainingCatalogGenerativeSurfaceRecord
{
	GENERATED_BODY()

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

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

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

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

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

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

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

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

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	TArray<FHyperTwistTrainingCatalogGenerativeSelectorRecord> selectors;

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

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

	bool IsStructurallyValid() const
	{
		return !source.IsEmpty()
			&& !source_scope.IsEmpty()
			&& !family.IsEmpty()
			&& !mode_id.IsEmpty()
			&& !mode_name.IsEmpty();
	}
};

USTRUCT(BlueprintType)
struct FHyperTwistTrainingCatalogRawExerciseRecord
{
	GENERATED_BODY()

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

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

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

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

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

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

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

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

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	TArray<FHyperTwistTrainingCatalogRawAlgorithmVariant> algorithm_variants;

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

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

	bool IsStructurallyValid() const
	{
		return !source.IsEmpty()
			&& !source_scope.IsEmpty()
			&& !family.IsEmpty()
			&& !case_id.IsEmpty()
			&& !exercise_type.IsEmpty();
	}
};

USTRUCT(BlueprintType)
struct FHyperTwistTrainingCatalogReferenceTarget
{
	GENERATED_BODY()

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

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

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

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

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

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

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

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

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

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

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

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

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	FHyperTwistTrainingCatalogRuntimeBundleMatchFilter MatchFilter;

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

	bool IsStructurallyValid() const
	{
		return !ReferenceTargetId.IsEmpty()
			&& !SurfaceType.IsEmpty()
			&& !ItemTitle.IsEmpty()
			&& !IncorporationChannel.IsEmpty();
	}
};

USTRUCT(BlueprintType)
struct FHyperTwistTrainingCatalogReferenceTargetDocument
{
	GENERATED_BODY()

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

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	TArray<FHyperTwistTrainingCatalogReferenceTarget> reference_targets;

	bool IsStructurallyValid() const
	{
		return !generated_at.IsEmpty() && reference_targets.Num() > 0;
	}
};

USTRUCT(BlueprintType)
struct FHyperTwistTrainingCatalogMaterializationCounts
{
	GENERATED_BODY()

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	int32 content_packs = 0;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	int32 track_manifests = 0;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	int32 deck_import_specs = 0;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	int32 runtime_content_bundles = 0;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	int32 reference_targets = 0;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	int32 overlap_pruned_exclusions = 0;

	bool IsStructurallyValid() const
	{
		return content_packs >= 0
			&& track_manifests >= 0
			&& deck_import_specs >= 0
			&& runtime_content_bundles >= 0
			&& reference_targets >= 0
			&& overlap_pruned_exclusions >= 0;
	}
};

USTRUCT(BlueprintType)
struct FHyperTwistTrainingCatalogMaterializationSummary
{
	GENERATED_BODY()

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

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

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

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	FHyperTwistTrainingCatalogMaterializationCounts counts;

	bool IsStructurallyValid() const
	{
		return !generated_at.IsEmpty()
			&& !slice.IsEmpty()
			&& !slice_status.IsEmpty()
			&& counts.IsStructurallyValid();
	}
};

USTRUCT(BlueprintType)
struct FHyperTwistTrainingCatalogMaterializedBundle
{
	GENERATED_BODY()

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

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	FHyperTwistTrainingCatalogContentPackManifestDocument ContentPackManifests;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	FHyperTwistTrainingCatalogDeckImportSpecDocument DeckImportSpecs;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	FHyperTwistTrainingCatalogRuntimeContentBundleDocument RuntimeContentBundles;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	FHyperTwistTrainingCatalogReferenceTargetDocument ReferenceTargets;

	bool IsStructurallyValid() const
	{
		return Summary.IsStructurallyValid()
			&& ContentPackManifests.IsStructurallyValid()
			&& DeckImportSpecs.IsStructurallyValid()
			&& RuntimeContentBundles.IsStructurallyValid()
			&& ReferenceTargets.IsStructurallyValid();
	}
};

USTRUCT(BlueprintType)
struct FHyperTwistTrainingCatalogImportLoadReport
{
	GENERATED_BODY()

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

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

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

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

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

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

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	int32 LoadedContentPackCount = 0;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	int32 LoadedTrackManifestCount = 0;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	int32 LoadedDeckImportSpecCount = 0;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	int32 LoadedRuntimeBundleCount = 0;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	int32 LoadedReferenceTargetCount = 0;

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

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

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

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

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

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

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

	bool IsStructurallyValid() const
	{
		return bLoadedSummary
			&& bLoadedContentPackManifests
			&& bLoadedDeckImportSpecs
			&& bLoadedRuntimeBundles
			&& bLoadedReferenceTargets;
	}
};

USTRUCT(BlueprintType)
struct FHyperTwistRetainedHyperPuzzleCatalogEntry
{
	GENERATED_BODY()

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

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

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	EHyperTwistPuzzleFamily PuzzleFamily = EHyperTwistPuzzleFamily::Hypercube;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	int32 Dimension = 4;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	FString DefinitionVersion = TEXT("2026.04");

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	FString NotationProfile = TEXT("hyper-4d");

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	TArray<int32> SizeVector;

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

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

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

	bool IsStructurallyValid() const
	{
		return !PuzzleId.IsEmpty()
			&& !DisplayName.IsEmpty()
			&& Dimension > 0
			&& !DefinitionVersion.IsEmpty()
			&& !NotationProfile.IsEmpty()
			&& SizeVector.Num() == Dimension;
	}

	bool MatchesPuzzleId(const FString& CandidatePuzzleId) const
	{
		if (CandidatePuzzleId.Equals(PuzzleId, ESearchCase::IgnoreCase))
		{
			return true;
		}

		return AliasPuzzleIds.ContainsByPredicate([&CandidatePuzzleId](const FString& AliasPuzzleId)
		{
			return CandidatePuzzleId.Equals(AliasPuzzleId, ESearchCase::IgnoreCase);
		});
	}

	FHyperTwistPuzzleDefinitionRef ToDefinitionRef() const
	{
		FHyperTwistPuzzleDefinitionRef Definition;
		Definition.PuzzleId = PuzzleId;
		Definition.PuzzleFamily = PuzzleFamily;
		Definition.Dimension = Dimension;
		Definition.DefinitionVersion = DefinitionVersion;
		Definition.NotationProfile = NotationProfile;
		Definition.SizeVector = SizeVector;
		Definition.Variant = Variant;
		return Definition;
	}
};

USTRUCT(BlueprintType)
struct FHyperTwistRetainedHyperPuzzleCatalog
{
	GENERATED_BODY()

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	FString CatalogId = TEXT("retained/hyperspeedcube/hyper-puzzles");

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	FString CatalogVersion = TEXT("2026.05");

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	TArray<FHyperTwistRetainedHyperPuzzleCatalogEntry> Entries;

	bool IsStructurallyValid() const
	{
		if (CatalogId.IsEmpty() || CatalogVersion.IsEmpty() || Entries.Num() == 0)
		{
			return false;
		}

		for (const FHyperTwistRetainedHyperPuzzleCatalogEntry& Entry : Entries)
		{
			if (!Entry.IsStructurallyValid())
			{
				return false;
			}
		}

		return true;
	}
};
