#pragma once

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

USTRUCT(BlueprintType)
struct FHyperTwistTrainingSharedAssetFixtureReference
{
	GENERATED_BODY()

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

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

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

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

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

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

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

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

	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 !FixtureId.IsEmpty() && !Label.IsEmpty() && RelativePaths.Num() > 0 && !FixtureKind.IsEmpty()
			&& !UsagePosture.IsEmpty() && !LicensePosture.IsEmpty() && SourceAttribution.IsStructurallyValid();
	}
};

USTRUCT(BlueprintType)
struct FHyperTwistTrainingSharedAssetQaPackContract
{
	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> RequiredFixtureIds;

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

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

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

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

	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 FHyperTwistTrainingSharedAssetProvenanceBoundary
{
	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> AllowedShippingFixtureIds;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

USTRUCT(BlueprintType)
struct FHyperTwistTrainingSharedAssetReferenceBundle
{
	GENERATED_BODY()

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

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

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

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

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	TArray<FHyperTwistTrainingSharedAssetFixtureReference> FixtureReferences;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	TArray<FHyperTwistTrainingSharedAssetQaPackContract> QaPackContracts;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	TArray<FHyperTwistTrainingSharedAssetProvenanceBoundary> ProvenanceBoundaries;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	TArray<FHyperTwistTrainingSharedAssetRefreshPattern> RefreshPatterns;

	bool IsStructurallyValid() const
	{
		return !PrimaryQaPackContractId.IsEmpty() && !PrimaryProvenanceBoundaryId.IsEmpty()
			&& !PrimaryRefreshPatternId.IsEmpty() && FixtureReferences.Num() > 0;
	}
};

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

public:
	UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|SharedAssets")
	static FHyperTwistTrainingSharedAssetReferenceBundle BuildBundledSharedAssetReferenceBundle();

	UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training|SharedAssets")
	static bool TryGetFixtureReferenceById(
		const FHyperTwistTrainingSharedAssetReferenceBundle& Bundle,
		const FString& FixtureId,
		FHyperTwistTrainingSharedAssetFixtureReference& OutReference
	);

	UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training|SharedAssets")
	static bool TryGetQaPackContractById(
		const FHyperTwistTrainingSharedAssetReferenceBundle& Bundle,
		const FString& ContractId,
		FHyperTwistTrainingSharedAssetQaPackContract& OutContract
	);

	UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training|SharedAssets")
	static bool TryGetProvenanceBoundaryById(
		const FHyperTwistTrainingSharedAssetReferenceBundle& Bundle,
		const FString& BoundaryId,
		FHyperTwistTrainingSharedAssetProvenanceBoundary& OutBoundary
	);

	UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training|SharedAssets")
	static bool TryGetRefreshPatternById(
		const FHyperTwistTrainingSharedAssetReferenceBundle& Bundle,
		const FString& PatternId,
		FHyperTwistTrainingSharedAssetRefreshPattern& OutPattern
	);

	UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|SharedAssets")
	static FString BuildFixtureChecklistTsv(const FHyperTwistTrainingSharedAssetReferenceBundle& Bundle);
};
