#pragma once

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

USTRUCT(BlueprintType)
struct FHyperTwistTrainingSpatialPackageReference
{
	GENERATED_BODY()

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

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

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

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

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

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

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

	bool IsStructurallyValid() const
	{
		return !PackageId.IsEmpty() && !Label.IsEmpty() && !OwnershipRole.IsEmpty()
			&& SourceAttribution.IsStructurallyValid();
	}
};

USTRUCT(BlueprintType)
struct FHyperTwistTrainingSpatialSceneContract
{
	GENERATED_BODY()

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

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

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

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

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

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

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

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

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

USTRUCT(BlueprintType)
struct FHyperTwistTrainingSpatialXrSessionContract
{
	GENERATED_BODY()

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

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

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

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

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

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

	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 !ContractId.IsEmpty() && !Title.IsEmpty() && SourceAttribution.IsStructurallyValid();
	}
};

USTRUCT(BlueprintType)
struct FHyperTwistTrainingSpatialUiContract
{
	GENERATED_BODY()

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

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

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

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

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

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

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

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

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

USTRUCT(BlueprintType)
struct FHyperTwistTrainingSpatialEffectBoundary
{
	GENERATED_BODY()

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

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

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

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

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

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

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

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

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

USTRUCT(BlueprintType)
struct FHyperTwistTrainingSpatialStateMotionContract
{
	GENERATED_BODY()

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

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

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

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

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

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

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

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

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

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

USTRUCT(BlueprintType)
struct FHyperTwistTrainingSpatialReferenceBundle
{
	GENERATED_BODY()

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

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

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

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

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

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

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	TArray<FHyperTwistTrainingSpatialPackageReference> PackageReferences;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	TArray<FHyperTwistTrainingSpatialSceneContract> SceneContracts;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	TArray<FHyperTwistTrainingSpatialXrSessionContract> XrSessionContracts;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	TArray<FHyperTwistTrainingSpatialUiContract> SpatialUiContracts;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	TArray<FHyperTwistTrainingSpatialEffectBoundary> EffectBoundaries;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	TArray<FHyperTwistTrainingSpatialStateMotionContract> StateMotionContracts;

	bool IsStructurallyValid() const
	{
		return !PrimarySceneContractId.IsEmpty() && !PrimaryXrSessionContractId.IsEmpty()
			&& !PrimarySpatialUiContractId.IsEmpty() && !PrimaryEffectBoundaryId.IsEmpty()
			&& !PrimaryStateMotionContractId.IsEmpty() && PackageReferences.Num() > 0;
	}
};

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

public:
	UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Spatial")
	static FHyperTwistTrainingSpatialReferenceBundle BuildBundledBrowserSpatialReferenceBundle();

	UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training|Spatial")
	static bool TryGetSceneContractById(
		const FHyperTwistTrainingSpatialReferenceBundle& Bundle,
		const FString& ContractId,
		FHyperTwistTrainingSpatialSceneContract& OutContract
	);

	UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training|Spatial")
	static bool TryGetXrSessionContractById(
		const FHyperTwistTrainingSpatialReferenceBundle& Bundle,
		const FString& ContractId,
		FHyperTwistTrainingSpatialXrSessionContract& OutContract
	);

	UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training|Spatial")
	static bool TryGetSpatialUiContractById(
		const FHyperTwistTrainingSpatialReferenceBundle& Bundle,
		const FString& ContractId,
		FHyperTwistTrainingSpatialUiContract& OutContract
	);

	UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training|Spatial")
	static bool TryGetEffectBoundaryById(
		const FHyperTwistTrainingSpatialReferenceBundle& Bundle,
		const FString& BoundaryId,
		FHyperTwistTrainingSpatialEffectBoundary& OutBoundary
	);

	UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training|Spatial")
	static bool TryGetStateMotionContractById(
		const FHyperTwistTrainingSpatialReferenceBundle& Bundle,
		const FString& ContractId,
		FHyperTwistTrainingSpatialStateMotionContract& OutContract
	);

	UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Spatial")
	static FString BuildPackageChecklistTsv(const FHyperTwistTrainingSpatialReferenceBundle& Bundle);
};
