/**
 * Copyright 2022-2025 Theai, Inc. dba Inworld AI
 */

#pragma once

#include "CoreMinimal.h"

#if WITH_GAMEPLAY_DEBUGGER

#include "GameplayDebuggerCategory.h"

class AActor;
class APlayerController;

/**
 * @class FGameplayDebuggerCategory_Inworld
 * @brief Gameplay debugger category for displaying Inworld Runtime debugging information.
 *
 * This class provides visual debugging capabilities for the Inworld Runtime system,
 * displaying graph execution history, node performance metrics, and error information
 * through the Unreal Engine gameplay debugger interface.
 */
class FGameplayDebuggerCategory_Inworld : public FGameplayDebuggerCategory
{
	using Super = FGameplayDebuggerCategory;

public:
	FGameplayDebuggerCategory_Inworld();

	/**
	 * @brief Creates a new instance of the Inworld debugger category.
	 * @return Shared reference to the created debugger category instance.
	 */
	static TSharedRef<FGameplayDebuggerCategory> MakeInstance();

	/**
	 * @brief Collects debugging data from the selected actor.
	 * @param OwnerPC The player controller requesting the debug information.
	 * @param DebugActor The actor to collect debug data from.
	 */
	virtual void CollectData(APlayerController* OwnerPC, AActor* DebugActor) override;

	/**
	 * @brief Renders the collected debug data to the screen.
	 * @param OwnerPC The player controller requesting the debug visualization.
	 * @param CanvasContext The canvas context for rendering debug information.
	 */
	virtual void DrawData(APlayerController* OwnerPC, FGameplayDebuggerCanvasContext& CanvasContext) override;

protected:
	struct FRepData
	{
		// FString LastNodeName;
		// double LastNodeDuration;
		// FString SlowestNodeName;
		// double SlowestNodeDuration;
		int32 MaxOwnerNum;

		struct FOldHistory
		{
			FString GraphName;
			FString ExecutionId;
			FString ErrorMessage;
		};
		TArray<FOldHistory> OldHistoryList;

		FString GraphName;
		FString ExecutionId;
		FString ErrorMessage;

		struct FNodeDebug
		{
			FString NodeName;
			double NodeTime;
			FString NodeDetail;
		};
		TArray<FNodeDebug> NodeDebugList;

		void Serialize(FArchive& Ar);
	};
	FRepData DataPack;

	TWeakObjectPtr<UObject> OwnerWeakPtr;

	int32 HistoryIndex = INDEX_NONE;
	int32 HistoryOwnerIndex = INDEX_NONE;

	void OnHistoryIndexIncrement();
	void OnHistoryIndexDecrement();
	void OnOwnerIndexIncrement();
	void OnOwnerIndexDecrement();
	void OnClearHistory();

	void ChangeHistoryIndex(const int32 Step);
	void ChangeOwnerIndex(const int32 Step);

	UObject* GetHistoryOwner();
};

#endif	  // WITH_GAMEPLAY_DEBUGGER
