#pragma once

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

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

public:
	UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Catalog")
	static FHyperTwistRetainedHyperPuzzleCatalog MakeRetainedHyperPuzzleCatalog();

	UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training|Catalog")
	static bool TryGetRetainedHyperPuzzleCatalogEntry(
		const FString& PuzzleId,
		FHyperTwistRetainedHyperPuzzleCatalogEntry& OutEntry
	);

	UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training|Catalog")
	static bool TryResolveRetainedHyperPuzzleDefinition(
		const FString& PuzzleId,
		FHyperTwistPuzzleDefinitionRef& OutDefinition
	);

	UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Catalog")
	static FHyperTwistContentPack MakeAlgTrainerStarterContentPack();

	UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Catalog")
	static FHyperTwistContentPack MakeCrossTrainerStarterContentPack();

	UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Catalog")
	static FHyperTwistContentPack MakeFiveStyleStarterContentPack();

	UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Catalog")
	static TArray<FHyperTwistContentPack> MakePhase3TrainingCatalog();

	UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Catalog")
	static FString GetBundledCatalogMaterializationDirectory();

	UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training|Catalog")
	static bool LoadCatalogMaterializationBundleFromDirectory(
		const FString& CatalogDirectory,
		FHyperTwistTrainingCatalogMaterializedBundle& OutBundle,
		FHyperTwistTrainingCatalogImportLoadReport& OutLoadReport
	);

	UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training|Catalog")
	static bool LoadBundledCatalogMaterializationBundle(
		FHyperTwistTrainingCatalogMaterializedBundle& OutBundle,
		FHyperTwistTrainingCatalogImportLoadReport& OutLoadReport
	);

	UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training|Catalog")
	static bool TryFindDeckImportSpecInMaterializedBundle(
		const FHyperTwistTrainingCatalogMaterializedBundle& MaterializedBundle,
		const FString& DeckId,
		FHyperTwistTrainingCatalogDeckImportSpec& OutDeckImportSpec
	);

	UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training|Catalog")
	static bool TryFindRuntimeContentBundleForDeckImportSpec(
		const FHyperTwistTrainingCatalogMaterializedBundle& MaterializedBundle,
		const FHyperTwistTrainingCatalogDeckImportSpec& DeckImportSpec,
		FHyperTwistTrainingCatalogRuntimeContentBundle& OutRuntimeBundle
	);

	UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training|Catalog")
	static bool TryFindReferenceTargetInMaterializedBundle(
		const FHyperTwistTrainingCatalogMaterializedBundle& MaterializedBundle,
		const FString& ReferenceTargetId,
		FHyperTwistTrainingCatalogReferenceTarget& OutReferenceTarget
	);

	UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training|Catalog")
	static bool TryMaterializeImportedDeckFromMaterializedBundle(
		const FHyperTwistTrainingCatalogMaterializedBundle& MaterializedBundle,
		const FString& DeckId,
		FHyperTwistTrainingDeck& OutDeck,
		FHyperTwistTrainingCatalogImportLoadReport& OutLoadReport
	);

	UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training|Catalog")
	static bool TryMaterializeImportedDeckFromBundledCatalog(
		const FString& DeckId,
		FHyperTwistTrainingDeck& OutDeck,
		FHyperTwistTrainingCatalogImportLoadReport& OutLoadReport
	);

	UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training|Catalog")
	static bool TryConvertImportedSourceAttribution(
		const FHyperTwistTrainingCatalogImportedSourceAttribution& ImportedAttribution,
		FHyperTwistTrainingSourceAttribution& OutSourceAttribution
	);

	UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training|Catalog")
	static bool TryConvertImportedPromptKind(
		const FString& ImportedPromptKind,
		EHyperTwistTrainingPromptKind& OutPromptKind
	);

	UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training|Catalog")
	static bool TryConvertImportedSelectionPolicy(
		const FString& ImportedSelectionPolicy,
		EHyperTwistTrainingSelectionPolicy& OutSelectionPolicy
	);

	UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training|Catalog")
	static bool TryConvertImportedDeliveryModes(
		const TArray<FString>& ImportedDeliveryModes,
		TArray<EHyperTwistTrainingDeliveryMode>& OutDeliveryModes
	);

	UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training|Catalog")
	static bool TryConvertImportedPuzzleFamily(
		const FString& ImportedPuzzleFamily,
		EHyperTwistPuzzleFamily& OutPuzzleFamily
	);

	UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training|Catalog")
	static bool TryFindDeckInCatalog(
		const TArray<FHyperTwistContentPack>& TrainingCatalog,
		const FString& DeckId,
		FHyperTwistTrainingDeck& OutDeck
	);

	UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training|Catalog")
	static bool TryGetTrackFromContentPack(
		const FHyperTwistContentPack& ContentPack,
		const FString& TrackId,
		FHyperTwistTrainingTrack& OutTrack
	);

	UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training|Catalog")
	static bool TryGetDeckFromContentPack(
		const FHyperTwistContentPack& ContentPack,
		const FString& TrackId,
		const FString& DeckId,
		FHyperTwistTrainingDeck& OutDeck
	);

	UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training|Catalog")
	static bool TryGetDefaultDeckFromContentPack(
		const FHyperTwistContentPack& ContentPack,
		FHyperTwistTrainingDeck& OutDeck
	);

	UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training|Catalog")
	static bool TryGetImportedRuntimeSurfaceFromDeck(
		const FHyperTwistTrainingDeck& Deck,
		FHyperTwistTrainingImportedRuntimeSurface& OutRuntimeSurface
	);

	UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training|Catalog")
	static bool TryGetImportedRuntimeSelectorFromDeck(
		const FHyperTwistTrainingDeck& Deck,
		const FString& SelectorId,
		FHyperTwistTrainingImportedRuntimeSelector& OutSelector
	);

	UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training|Catalog")
	static bool TryGetImportedRuntimeSelectorOptionCasesFromDeck(
		const FHyperTwistTrainingDeck& Deck,
		const FString& SelectorId,
		TArray<FHyperTwistTrainingCase>& OutCases
	);

	UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training|Catalog")
	static bool TryGetImportedRuntimeSelectorOptionCaseFromDeck(
		const FHyperTwistTrainingDeck& Deck,
		const FString& SelectorId,
		const FString& OptionId,
		FHyperTwistTrainingCase& OutCase
	);

	UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training|Catalog")
	static bool TryBuildImportedGeneratedModeLaunchConfig(
		const FHyperTwistTrainingDeck& Deck,
		const FHyperTwistTrainingImportedRuntimeSelectionState& ImportedRuntimeSelectionState,
		const FHyperTwistTrainingSession& Session,
		FHyperTwistTrainingImportedGeneratedModeLaunchConfig& OutLaunchConfig
	);

	UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Catalog")
	static FHyperTwistTrainingMethodDescriptor DescribeTrainingDeckMethod(
		const FHyperTwistTrainingDeck& Deck
	);

	UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training|Catalog")
	static bool TryDescribeDeckMethodFromCatalog(
		const TArray<FHyperTwistContentPack>& TrainingCatalog,
		const FString& DeckId,
		FHyperTwistTrainingMethodDescriptor& OutDescriptor
	);

	UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Catalog")
	static FHyperTwistTrainingDeck MaterializeTrainingSessionTemplateDeck(
		const FHyperTwistTrainingSessionTemplate& SessionTemplate,
		const TArray<FHyperTwistContentPack>& TrainingCatalog
	);
};
