// Copyright (c) 2022 Codemongous LLC. All Rights Reserved.

#pragma once

#include "CoreMinimal.h"
#include "ContentBrowserDelegates.h"
#include "EdGraphUtilities.h"
#include "ISCW_UnrealEngine.h"
#include "Modules/ModuleManager.h"
#include "SourcifyCore.h"

DECLARE_LOG_CATEGORY_EXTERN(LogSourcify, Display, Display);

class FToolBarBuilder;
class FMenuBuilder;
class SSourcifyGraph;
class SSourcifyResults;

namespace Sourcify
{
	class ISourcifyCore;
}

DECLARE_MULTICAST_DELEGATE_OneParam(FOnSourcifyingComplete, Sourcify::Results);

class FSourcifyModule : public IModuleInterface
{
public:

	/** IModuleInterface implementation */
	virtual void StartupModule() override;
	virtual void ShutdownModule() override;
	
	static inline FSourcifyModule& Get()
	{
		return FModuleManager::LoadModuleChecked<FSourcifyModule>("Sourcify");
	}

	void RegisterMenus();

	TSharedRef<class FExtender> ContextMenuBuilder(const TArray<struct FAssetData>& selectedAssets);
	void MakeContextMenu(class FMenuBuilder& menuBuilder, const TArray<struct FAssetData>& selectedAssets);

	void SetupGraph(const TArray<struct FAssetData>& selectedAssets, SSourcifyGraph& graph);
#if SOURCIFY_DEBUG
	void ScanBlueprint(const TArray<struct FAssetData>& SelectedAssets);
#endif
	TSharedRef<SDockTab> SpawnSourcifyGraphTab(const FSpawnTabArgs& Args);
	TSharedRef<SDockTab> SpawnSourcifyResultsTab(const FSpawnTabArgs& Args);
	Sourcify::ISourcifyCore& GetSourcifyCoreInstance() { return *SC; };
	Sourcify::Results Sourcify();

	void ReportSourcifyResults() const;

	/** Called when Sourcifying has completed or has failed */
	FOnSourcifyingComplete OnSourcifyingComplete;

	/** Check for a valid license */
	Sourcify::LicenseStatus GetLicenseStatus() const;

	/** Returns license status string, empty if license ok. */
	FString GetLicenseStatusMessage() const;

	/** Activate a license key. Returns error string, empty if activation ok. */
	Sourcify::LicenseStatus ActivateLicense(const FString& InKey) const;

	/** Deactivate user's current license. Returns error string, empty if activation ok. */
	Sourcify::LicenseStatus DeactivateCurrentLicense() const;

	/** Gets the current status of the License Manager */
	Sourcify::LicenseStatus CheckLicense() const;

	/** Gets the current user's license information */
	Sourcify::LicenseHolderInfo GetLicenseHolderInfo() const;

	/** Returns if it is safe to perform a license action */
	bool IsLicenseActionAllowed() const;

	/** Returns if a trial sourcification is allowed given the current asset */
	bool IsTrialSourcificationAllowed() const;

	/** Refreshes the currently open Sourcify Graph */
	void RefreshCurrentGraph();

	Sourcify::ISCW_UnrealEnginePtr GetIUE() const { return IUE; }

	const Sourcify::BlueprintDependencies* GetPreSourcifyDependencies() const { return PreSourcifyDependencies; }

	bool IsNewVersionAvailable() const;

private:
	FContentBrowserMenuExtender_SelectedAssets _ContextMenuExtension;

	FName SourcifyGraphTabName;
	TWeakPtr<SDockTab> SourcifyGraphTab;
	TWeakPtr<SSourcifyGraph> SourcifyGraphUI;
	TSharedPtr<FGraphPanelNodeFactory> SourcifyGraphPanelNodeFactory;
	TSharedPtr<FGraphPanelPinFactory> SourcifyGraphPanelPinFactory;
	
	FName SourcifyResultsTabName;
	TWeakPtr<SDockTab> SourcifyResultsTab;
	
	Sourcify::ISourcifyCore* SC = nullptr;

	mutable bool IsSourcifying = false;
	mutable const Sourcify::BlueprintDependencies* PreSourcifyDependencies = nullptr;
	TWeakObjectPtr<UObject> AssetBeingSourcified;
	Sourcify::ISCW_UnrealEnginePtr IUE;

	Sourcify::Results SourcifyResults;
	bool NewVersionAvailable = false;
	void CheckPluginVersion();
	void CheckAndPromptForDefaultCodeExportPath();
};
