#pragma once

#include "CoreMinimal.h"
#include "EditorUtilityObject.h"
#include "Extensions/DruidsMCPBridgeSageExtensionTypes.h"
#include "DruidsMCPBridgeSageExtension.generated.h"

UCLASS(Blueprintable, meta = (DisplayName = "Sage Extension"))
class DRUIDSMCPBRIDGE_API UDruidsMCPBridgeSageExtension : public UEditorUtilityObject
{
	GENERATED_BODY()

public:
	UDruidsMCPBridgeSageExtension();

	UFUNCTION(BlueprintNativeEvent, Category = "Sage Extension")
	bool IsActive() const;
	virtual bool IsActive_Implementation() const;

	UFUNCTION(BlueprintCallable, Category = "Sage Extension")
	void DiscoverActionsAndQueries();

	UFUNCTION(BlueprintCallable, Category = "Sage Extension")
	static void ReportExtensionError(const FString& ErrorMessage);

	UFUNCTION(BlueprintCallable, Category = "Sage Extension")
	static void ReportExtensionResults(const FString& ResultsMessage);

	UFUNCTION(BlueprintCallable, BlueprintPure, Category = "Sage Extension")
	static UWorld* GetWorldEditorContext();

	UFUNCTION(BlueprintCallable, Category = "Sage Extension", meta = (DisplayName = "Get Currently Edited Asset"))
	static UObject* GetCurrentlyEditedAsset();

	bool IsEnabled() const;
	virtual bool IsSystemExtension() const;
	virtual bool MatchesContext(TWeakObjectPtr<UObject> ActiveObject) const;

	TSharedPtr<FDruidsMCPBridgeSageExtensionDefinition> GetExtensionDefinition() const;
	FDruidsMCPBridgeSageActionResult ExecuteAction(const TSharedPtr<FJsonObject>& ActionRequestDetails);
	TSharedPtr<FJsonValue> ExecuteQuery(const TSharedPtr<FJsonObject>& QueryRequestDetails);

	static void ClearExtensionError();
	static FString GetExtensionError();
	static bool HasExtensionError();

	static void ClearExtensionResults();
	static FString GetExtensionResults();
	static bool HasExtensionResults();

protected:
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Sage Extension")
	FDruidsMCPBridgeSageExtensionDefinition Definition;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Sage Extension")
	bool bEnabled = true;

	virtual void PostInitProperties() override;
	virtual void PostCDOCompiled(const FPostCDOCompiledContext& Context) override;

private:
	void RefreshExtension();
	void DiscoverFunction(UFunction* Function, const TMap<FString, FString>& ExistingDescriptions);
	bool ResolveFunctionName(const FString& RequestedName, bool bAction, FName& OutFunctionName) const;

	static bool BuildParamsFromJson(const UFunction* Function, const TSharedPtr<const FJsonObject>& JsonObject, TArray<uint8>& OutParamBuffer);
	static TSharedPtr<FJsonValue> GetJsonValueFromProperty(FProperty* Property, void* ValuePtr);
	static EDruidsMCPBridgeSageExtensionParameterType GetArrayInnerType(const FArrayProperty* ArrayProperty);
	static FString& GetCurrentExtensionError();
	static FString& GetCurrentExtensionResults();
};
