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

#include "CoreMinimal.h"
#include "Graph/Assets/InworldGraphAsset.h"
#include "GraphEditor.h"
#include "Misc/NotifyHook.h"
#include "Toolkits/AssetEditorToolkit.h"
#include "UObject/GCObject.h"
#include "UObject/ObjectSaveContext.h"
#include "Runtime/Launch/Resources/Version.h"

class FGGAssetEditorToolbar;
class SDockTab;

class INWORLDRUNTIMEEDITOR_API FAssetEditor_InworldGraph : public FAssetEditorToolkit, public FNotifyHook, public FGCObject
{
public:
	FAssetEditor_InworldGraph();
	virtual ~FAssetEditor_InworldGraph();

	void InitGraphAssetEditor(
		const EToolkitMode::Type Mode, const TSharedPtr<IToolkitHost>& InitToolkitHost, UInworldGraphAsset* Graph);

	// IToolkit interface
	virtual void RegisterTabSpawners(const TSharedRef<FTabManager>& TabManager) override;
	virtual void UnregisterTabSpawners(const TSharedRef<FTabManager>& TabManager) override;
	// End of IToolkit interface

	// FAssetEditorToolkit
	virtual FName GetToolkitFName() const override;
	virtual FText GetBaseToolkitName() const override;
	virtual FText GetToolkitName() const override;
	virtual FText GetToolkitToolTipText() const override;
	virtual FLinearColor GetWorldCentricTabColorScale() const override;
	virtual FString GetWorldCentricTabPrefix() const override;
	virtual FString GetDocumentationLink() const override;
	virtual void SaveAsset_Execute() override;
	// End of FAssetEditorToolkit

	// Toolbar
	TSharedPtr<class FAssetEditorToolbar_InworldGraph> GetToolbarBuilder()
	{
		return ToolbarBuilder;
	}
	void RegisterToolbarTab(const TSharedRef<class FTabManager>& TabManager);

	// FSerializableObject interface
	virtual void AddReferencedObjects(FReferenceCollector& Collector) override;
	// End of FSerializableObject interface

	// FGCObject interface
	virtual FString GetReferencerName() const
	{
		return TEXT("FAssetEditor_LTInworldGraph");
	}
	// ~FGCObject interface

protected:
	TSharedRef<SDockTab> SpawnTab_Viewport(const FSpawnTabArgs& Args);
	TSharedRef<SDockTab> SpawnTab_Details(const FSpawnTabArgs& Args);
	TSharedRef<SDockTab> SpawnTab_GraphSettings(const FSpawnTabArgs& Args);

	void CreateInternalWidgets();
	TSharedRef<SGraphEditor> CreateViewportWidget();

	void BindCommands();

	void CreateEdGraph();

	void CreateCommandList();

	TSharedPtr<SGraphEditor> GetCurrGraphEditor() const;

	FGraphPanelSelectionSet GetSelectedNodes() const;

	void SanitizeGraphClipboard(FString& Text);
	// Delegates for graph editor commands
	void SelectAllNodes();
	bool CanSelectAllNodes();
	void DeleteSelectedNodes();
	bool CanDeleteNodes();
	void DeleteSelectedDuplicatableNodes();
	void CutSelectedNodes();
	bool CanCutNodes();
	void CopySelectedNodes();
	bool CanCopyNodes();
	void PasteNodes();
#if ENGINE_MAJOR_VERSION == 5 && ENGINE_MINOR_VERSION < 6
	void PasteNodesHere(const FVector2D& Location);
#else
	void PasteNodesHere(const FVector2f& Location);
#endif
	bool CanPasteNodes();
	void DuplicateNodes();
	bool CanDuplicateNodes();

	bool CanCreateComment() const;
	void OnCreateComment();

	void CopyJSON();
	void CreateCustomNode();
	void CreateCustomEdge();
	bool CanGenerateJSON() const;
	bool CanGraphSettings() const;
	bool CanCreateCustom() const;

	void HandleCreateModeAsset(UClass* InClass) const;

	void OnRenameNode();
	bool CanRenameNodes() const;

	//////////////////////////////////////////////////////////////////////////
	// graph editor event
	void OnSelectedNodesChanged(const TSet<class UObject*>& NewSelection);

	void OnNodeDoubleClicked(UEdGraphNode* Node);

	void OnFinishedChangingProperties(const FPropertyChangedEvent& PropertyChangedEvent);
	void OnNodeTextCommitted(const FText& NewText, ETextCommit::Type CommitInfo, UEdGraphNode* NodeBeingChanged);

protected:
	UPROPERTY()
	TObjectPtr<UInworldGraphAsset> EditingGraph;

	// Toolbar
	TSharedPtr<class FAssetEditorToolbar_InworldGraph> ToolbarBuilder;

	/** Handle to the registered OnPackageSave delegate */
	FDelegateHandle OnPackageSavedDelegateHandle;

	TSharedPtr<SGraphEditor> ViewportWidget;
	TSharedPtr<class IDetailsView> PropertyWidget;
	TSharedPtr<class IDetailsView> EditorSettingsWidget;

	/** The command list for this editor */
	TSharedPtr<FUICommandList> GraphEditorCommands;
};
