#pragma once

#include "CoreMinimal.h"
#include "Dom/JsonObject.h"
#include "DruidsMCPBridgeSageExtensionTypes.generated.h"

UENUM(BlueprintType, meta = (DisplayName = "Sage Extension Context Type"))
enum class EDruidsMCPBridgeSageExtensionContextType : uint8
{
	Any,
	AssetEditor
};

UENUM(BlueprintType, meta = (DisplayName = "Sage Extension Parameter Type"))
enum class EDruidsMCPBridgeSageExtensionParameterType : uint8
{
	None,
	String,
	Int,
	Float,
	Bool,
	Vector3,
	Color,
	Rotator,
	LinearColor,
	Enum,
	Array,
	Transform,
	CustomStruct,
	Object
};

USTRUCT(BlueprintType, meta = (DisplayName = "Sage Action Result"))
struct DRUIDSMCPBRIDGE_API FDruidsMCPBridgeSageActionResult
{
	GENERATED_BODY()

	UPROPERTY(BlueprintReadOnly, Category = "Sage Extension")
	bool bActionCalled = false;

	UPROPERTY(BlueprintReadOnly, Category = "Sage Extension")
	bool bSuccess = false;

	UPROPERTY(BlueprintReadOnly, Category = "Sage Extension")
	bool bIsAsync = false;

	UPROPERTY(BlueprintReadOnly, Category = "Sage Extension")
	FString Result;

	UPROPERTY(BlueprintReadOnly, Category = "Sage Extension")
	FString ErrorMessage;

	static FDruidsMCPBridgeSageActionResult NoAction();
	static FDruidsMCPBridgeSageActionResult ExtensionSuccess(const FString& InResult = TEXT(""));
	static FDruidsMCPBridgeSageActionResult ExtensionFailure(const FString& InErrorMessage);
	static FDruidsMCPBridgeSageActionResult AsyncAction(const FString& InResult = TEXT("Extension async action started"));
};

USTRUCT(BlueprintType, meta = (DisplayName = "Sage Parameter Definition"))
struct DRUIDSMCPBRIDGE_API FDruidsMCPBridgeSageParameterDefinition
{
	GENERATED_BODY()

	UPROPERTY(BlueprintReadOnly, VisibleAnywhere, Category = "Sage Extension")
	FName Name = NAME_None;

	UPROPERTY(BlueprintReadOnly, VisibleAnywhere, Category = "Sage Extension")
	EDruidsMCPBridgeSageExtensionParameterType ParameterType = EDruidsMCPBridgeSageExtensionParameterType::None;

	UPROPERTY(BlueprintReadOnly, VisibleAnywhere, Category = "Sage Extension")
	EDruidsMCPBridgeSageExtensionParameterType ArrayElementType = EDruidsMCPBridgeSageExtensionParameterType::None;

	UPROPERTY(BlueprintReadOnly, VisibleAnywhere, Category = "Sage Extension")
	TWeakObjectPtr<UScriptStruct> StructElementType;

	UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Sage Extension", meta = (MultiLine = "true"))
	FString Description;

	UPROPERTY(BlueprintReadOnly, Category = "Sage Extension")
	FString ParameterTypeJsonString;

	void RefreshJsonString(const FProperty* Property);

	static EDruidsMCPBridgeSageExtensionParameterType GetParameterTypeForProperty(const FProperty* Property);
	static FString GetParameterStringForType(EDruidsMCPBridgeSageExtensionParameterType ParameterType);

private:
	static void InsertPropertyAsJson(const TSharedPtr<FJsonObject>& ParamObject, const FProperty* Property);
	static TSharedPtr<FJsonObject> GetArrayTypeAsJson(const FProperty* ArrayType);
	static TSharedPtr<FJsonObject> GetStructTypeInfo(TWeakObjectPtr<UScriptStruct> StructType);
};

USTRUCT(BlueprintType, meta = (DisplayName = "Sage Extension Action Definition"))
struct DRUIDSMCPBRIDGE_API FDruidsMCPBridgeSageActionDefinition
{
	GENERATED_BODY()

	UPROPERTY(BlueprintReadOnly, VisibleAnywhere, Category = "Sage Extension")
	FName FunctionName = NAME_None;

	UPROPERTY(BlueprintReadOnly, VisibleAnywhere, Category = "Sage Extension", meta = (MultiLine = "true"))
	FString Description;

	UPROPERTY(BlueprintReadOnly, EditAnywhere, Category = "Sage Extension")
	TArray<FDruidsMCPBridgeSageParameterDefinition> ParameterDefinitions;
};

USTRUCT(BlueprintType, meta = (DisplayName = "Sage Extension Query Definition"))
struct DRUIDSMCPBRIDGE_API FDruidsMCPBridgeSageQueryDefinition
{
	GENERATED_BODY()

	UPROPERTY(BlueprintReadOnly, VisibleAnywhere, Category = "Sage Extension")
	FName FunctionName = NAME_None;

	UPROPERTY(BlueprintReadOnly, VisibleAnywhere, Category = "Sage Extension", meta = (MultiLine = "true"))
	FString Description;

	UPROPERTY(BlueprintReadOnly, EditAnywhere, Category = "Sage Extension")
	TArray<FDruidsMCPBridgeSageParameterDefinition> ParameterDefinitions;

	UPROPERTY(BlueprintReadOnly, EditAnywhere, Category = "Sage Extension")
	TArray<FDruidsMCPBridgeSageParameterDefinition> ResultDefinitions;
};

USTRUCT(BlueprintType, meta = (DisplayName = "Sage Extension Definition"))
struct DRUIDSMCPBRIDGE_API FDruidsMCPBridgeSageExtensionDefinition
{
	GENERATED_BODY()

	UPROPERTY(BlueprintReadOnly, VisibleAnywhere, Category = "Sage Extension")
	FString ExtensionId;

	UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Sage Extension")
	FString ExtensionName;

	UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Sage Extension", meta = (MultiLine = "true"))
	FString ExtensionDescription;

	UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Sage Extension")
	EDruidsMCPBridgeSageExtensionContextType ContextType = EDruidsMCPBridgeSageExtensionContextType::Any;

	UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Sage Extension")
	FString SelectedAssetType;

	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Sage Extension")
	TArray<FDruidsMCPBridgeSageActionDefinition> Actions;

	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Sage Extension")
	TArray<FDruidsMCPBridgeSageQueryDefinition> Queries;

	UPROPERTY(BlueprintReadOnly, VisibleAnywhere, Category = "Sage Extension")
	bool bIsSystemExtension = false;

	TSharedPtr<FJsonObject> GetExtensionDefinitionJson() const;
};
