#pragma once

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

USTRUCT(BlueprintType)
struct FHyperTwistTrainingClassicCubingPackageReference
{
	GENERATED_BODY()

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

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

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

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

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

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

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

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

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

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

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

USTRUCT(BlueprintType)
struct FHyperTwistTrainingClassicCubingSemanticContract
{
	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> PuzzleStateFields;

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

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

	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 FHyperTwistTrainingClassicCubingGeometryContract
{
	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> NamedPuzzleFamilies;

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

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

	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 FHyperTwistTrainingClassicCubingViewerAdapterContract
{
	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> ViewerSurfaceTags;

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

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

	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 FHyperTwistTrainingClassicCubingDeviceAdapterBoundary
{
	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> DeviceFamilies;

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

	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 FHyperTwistTrainingClassicCubingSearchContract
{
	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> PuzzleFamilies;

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

	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 FHyperTwistTrainingClassicCubingComplianceBoundary
{
	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> AllowedUseTags;

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

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

	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 FHyperTwistTrainingClassicCubingReferenceBundle
{
	GENERATED_BODY()

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

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

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

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

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

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

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

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

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	TArray<FHyperTwistTrainingClassicCubingSemanticContract> SemanticContracts;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	TArray<FHyperTwistTrainingClassicCubingGeometryContract> GeometryContracts;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	TArray<FHyperTwistTrainingClassicCubingViewerAdapterContract> ViewerAdapterContracts;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	TArray<FHyperTwistTrainingClassicCubingDeviceAdapterBoundary> DeviceAdapterBoundaries;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	TArray<FHyperTwistTrainingClassicCubingSearchContract> SearchContracts;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	TArray<FHyperTwistTrainingClassicCubingComplianceBoundary> ComplianceBoundaries;

	bool IsStructurallyValid() const
	{
		return !PrimarySemanticContractId.IsEmpty() && !PrimaryGeometryContractId.IsEmpty()
			&& !PrimaryViewerAdapterContractId.IsEmpty() && !PrimaryDeviceAdapterBoundaryId.IsEmpty()
			&& !PrimarySearchContractId.IsEmpty() && !PrimaryComplianceBoundaryId.IsEmpty()
			&& PackageReferences.Num() > 0;
	}
};

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

public:
	UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|ClassicCubing")
	static FHyperTwistTrainingClassicCubingReferenceBundle BuildBundledClassicCubingReferenceBundle();

	UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training|ClassicCubing")
	static bool TryGetSemanticContractById(
		const FHyperTwistTrainingClassicCubingReferenceBundle& Bundle,
		const FString& ContractId,
		FHyperTwistTrainingClassicCubingSemanticContract& OutContract
	);

	UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training|ClassicCubing")
	static bool TryGetGeometryContractById(
		const FHyperTwistTrainingClassicCubingReferenceBundle& Bundle,
		const FString& ContractId,
		FHyperTwistTrainingClassicCubingGeometryContract& OutContract
	);

	UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training|ClassicCubing")
	static bool TryGetViewerAdapterContractById(
		const FHyperTwistTrainingClassicCubingReferenceBundle& Bundle,
		const FString& ContractId,
		FHyperTwistTrainingClassicCubingViewerAdapterContract& OutContract
	);

	UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training|ClassicCubing")
	static bool TryGetDeviceAdapterBoundaryById(
		const FHyperTwistTrainingClassicCubingReferenceBundle& Bundle,
		const FString& BoundaryId,
		FHyperTwistTrainingClassicCubingDeviceAdapterBoundary& OutBoundary
	);

	UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training|ClassicCubing")
	static bool TryGetSearchContractById(
		const FHyperTwistTrainingClassicCubingReferenceBundle& Bundle,
		const FString& ContractId,
		FHyperTwistTrainingClassicCubingSearchContract& OutContract
	);

	UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training|ClassicCubing")
	static bool TryGetComplianceBoundaryById(
		const FHyperTwistTrainingClassicCubingReferenceBundle& Bundle,
		const FString& BoundaryId,
		FHyperTwistTrainingClassicCubingComplianceBoundary& OutBoundary
	);

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