#pragma once

#include "CoreMinimal.h"
#include "WingServer.h"
#include "WingBasics.h"
#include "WingUtils.h"
#include "AssetRegistry/AssetRegistryModule.h"
#include "AssetRegistry/AssetData.h"
#include "AssetRegistry/IAssetRegistry.h"
#include "Asset_ContentBrowse.generated.h"


// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------

UCLASS()
class UWing_Asset_ContentBrowse : public UWingHandler
{
	GENERATED_BODY()

public:
	UPROPERTY(EditAnywhere, meta=(Description="Content browser path to list, e.g. /Game or /Game/Maps"))
	FString Path;

	virtual void Register() override
	{
		UWingServer::AddHandler(this,
			TEXT("List the subfolders and assets inside a content browser folder."));
	}
	static FString GetExtraInfoString(const FAssetData& Data)
	{
		FString ParentClassName;
		if (Data.GetTagValue(FName(TEXT("ParentClass")), ParentClassName))
		{
			int32 DotIndex;
			if (ParentClassName.FindLastChar('.', DotIndex))
				ParentClassName = ParentClassName.Mid(DotIndex + 1);
			ParentClassName.RemoveFromEnd(TEXT("'"));
			return FString::Printf(TEXT("(parent: %s)"), *ParentClassName);
		}
		return FString();
	}

	static FString GetAssetTypeString(const FAssetData& Data)
	{
		FString AssetType = WingUtils::FormatName(Data.GetClass());
		FString BlueprintTypeTag;
		if (Data.GetTagValue(FName(TEXT("BlueprintType")), BlueprintTypeTag))
		{
			BlueprintTypeTag.RemoveFromStart(TEXT("BPTYPE_"));
			if (BlueprintTypeTag == TEXT("Normal"))
				AssetType = TEXT("Blueprint");
			else if (BlueprintTypeTag == TEXT("Const"))
				AssetType = TEXT("ConstBlueprint");
			else
				AssetType = BlueprintTypeTag;
		}
		return AssetType;
	}

	virtual void Handle() override
	{
		// Normalize: strip trailing slash
		while (Path.EndsWith(TEXT("/")))
		{
			Path.LeftChopInline(1);
		}

		IAssetRegistry& AR = FModuleManager::LoadModuleChecked<FAssetRegistryModule>("AssetRegistry").Get();

		TArray<FString> Results;
		AR.EnumerateSubPaths(Path, [&Results](FString SubPath)
		{
			Results.Add(FString::Printf(TEXT("[Folder] %s\n"), *SubPath));
			return true;
		}, false);

		// Collect assets in this folder (non-recursive)
		FARFilter Filter;
		Filter.PackagePaths.Add(FName(*Path));
		Filter.bRecursivePaths = false;
		TArray<FAssetData> Assets;
		AR.GetAssets(Filter, Assets);

		for (const FAssetData &Asset : Assets)
		{
			if (Asset.IsRedirector()) continue;
			FString TypeString = GetAssetTypeString(Asset);
			FString ExtraInfo = GetExtraInfoString(Asset);
			Results.Add(FString::Printf(TEXT("%-30s  %s  %s\n"),
				*TypeString, *Asset.PackageName.ToString(), *ExtraInfo));
		}

		Results.Sort();
		for (const FString &Result : Results) WingOut::Stdout.Print(Result);

		if (Results.IsEmpty())
		{
			WingOut::Stdout.Printf(TEXT("No contents found at '%s'.\n"), *Path);
			return;
		}
	}
};
