#pragma once

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

USTRUCT(BlueprintType)
struct FHyperTwistTrainingTilingPackageReference
{
	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 FHyperTwistTrainingTilingTopologyContract
{
	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> GeometrySurfaceTags;

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

	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 FHyperTwistTrainingTilingLoaderBoundary
{
	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> LoaderSurfaceTags;

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

	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 FHyperTwistTrainingTilingAttributionBoundary
{
	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> 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 FHyperTwistTrainingTilingMacroRemappingContract
{
	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> ReferenceSurfaceTags;

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

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

	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 FHyperTwistTrainingTilingMacroPersistenceBoundary
{
	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> PersistenceSurfaceTags;

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

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

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

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

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

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

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

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

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

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

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	TArray<FHyperTwistTrainingTilingTopologyContract> TopologyContracts;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	TArray<FHyperTwistTrainingTilingLoaderBoundary> LoaderBoundaries;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	TArray<FHyperTwistTrainingTilingAttributionBoundary> AttributionBoundaries;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	TArray<FHyperTwistTrainingTilingMacroRemappingContract> MacroRemappingContracts;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	TArray<FHyperTwistTrainingTilingMacroPersistenceBoundary> MacroPersistenceBoundaries;

	bool IsStructurallyValid() const
	{
		return !PrimaryTopologyContractId.IsEmpty() && !PrimaryLoaderBoundaryId.IsEmpty()
			&& !PrimaryAttributionBoundaryId.IsEmpty() && !PrimaryMacroRemappingContractId.IsEmpty()
			&& !PrimaryMacroPersistenceBoundaryId.IsEmpty() && PackageReferences.Num() > 0
			&& MacroRemappingContracts.Num() > 0 && MacroPersistenceBoundaries.Num() > 0;
	}
};

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

public:
	UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Tiling")
	static FHyperTwistTrainingTilingReferenceBundle BuildBundledTilingReferenceBundle();

	UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training|Tiling")
	static bool TryGetTopologyContractById(
		const FHyperTwistTrainingTilingReferenceBundle& Bundle,
		const FString& ContractId,
		FHyperTwistTrainingTilingTopologyContract& OutContract
	);

	UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training|Tiling")
	static bool TryGetLoaderBoundaryById(
		const FHyperTwistTrainingTilingReferenceBundle& Bundle,
		const FString& BoundaryId,
		FHyperTwistTrainingTilingLoaderBoundary& OutBoundary
	);

	UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training|Tiling")
	static bool TryGetAttributionBoundaryById(
		const FHyperTwistTrainingTilingReferenceBundle& Bundle,
		const FString& BoundaryId,
		FHyperTwistTrainingTilingAttributionBoundary& OutBoundary
	);

	UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training|Tiling")
	static bool TryGetMacroRemappingContractById(
		const FHyperTwistTrainingTilingReferenceBundle& Bundle,
		const FString& ContractId,
		FHyperTwistTrainingTilingMacroRemappingContract& OutContract
	);

	UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training|Tiling")
	static bool TryGetMacroPersistenceBoundaryById(
		const FHyperTwistTrainingTilingReferenceBundle& Bundle,
		const FString& BoundaryId,
		FHyperTwistTrainingTilingMacroPersistenceBoundary& OutBoundary
	);

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