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

#pragma once

#include "InworldTextClassifierTypes.generated.h"

INWORLDRUNTIME_API DECLARE_LOG_CATEGORY_EXTERN(LogInworldTextClassifier, Log, All);

/**
 * @struct FInworldTextClassifierInput
 * @brief Input for text classification.
 *
 * @param InputText
 * The text to classify. Maximum recommended length is 4096 characters.
 */
USTRUCT(BlueprintType)
struct FInworldTextClassifierInput
{
	GENERATED_BODY()
	/** Text to classify */
	UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = "Inworld|TextClassifier",
		Meta = (ToolTip = "The text to classify. Maximum recommended length is 4096 characters"))
	FString InputText;
};

/**
 * @struct FInworldClassThreshold
 * @brief Represents a class with its detection threshold.
 *
 * @param ClassLabel
 * The class label to detect.
 *
 * @param Threshold
 * Threshold value for detection sensitivity, ranging from 0.0 to 1.0.
 * - Values closer to 0.0 make the classifier more sensitive
 * - Values closer to 1.0 make the classifier less sensitive
 * - Typical recommended range is 0.5 to 0.8 for balanced classification.
 */
USTRUCT(BlueprintType)
struct FInworldClassThreshold
{
	GENERATED_BODY()

	/** The class label to detect */
	UPROPERTY(
		EditDefaultsOnly, BlueprintReadWrite, Category = "Inworld|TextClassifier", Meta = (ToolTip = "The class label to detect"))
	FString ClassLabel{""};
	/** Threshold value (0.0 to 1.0) for detection sensitivity */
	UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = "Inworld|TextClassifier",
		Meta = (ToolTip =
					"Threshold value (0.0 to 1.0) for detection sensitivity. Values closer to 0.0 make the classifier more sensitive, values closer to 1.0 make it less sensitive. Typical recommended range is 0.5 to 0.8"))
	float Threshold{0.5f};
};

/**
 * @struct FInworldTextClassifierConfig
 * @brief Configuration for text classification.
 *
 * @param Classes
 * TArray of FInworldClassThreshold structs specifying which classes to classify
 * and their detection thresholds.
 */
USTRUCT(BlueprintType)
struct FInworldTextClassifierConfig
{
	GENERATED_BODY()

	/** List of classes with their detection thresholds */
	UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = "Inworld|TextClassifier",
		Meta = (ToolTip = "Array of classes to classify and their detection thresholds"))
	TArray<FInworldClassThreshold> Classes;
};

/**
 * @struct FInworldTextClassifierCreationConfig
 * @brief Configuration for creating a text classifier.
 *
 * The model_weights_path must point to a trained model file that supports
 * the classes specified in supported_classes. If there's a mismatch between
 * the model's training data and supported_classes, the classifier may:
 * - Return low confidence scores for unsupported classes
 * - Fail to create with an error status
 * - Produce unreliable classification results
 *
 * Common supported classes include:
 * - Safety: "profanity", "hate_speech", "violence", "harassment",
 * "adult_content"
 * - Sentiment: "positive", "negative", "neutral"
 * - Intent: "question", "statement", "command", "request"
 * - Topic: "sports", "technology", "politics", "entertainment", "health"
 *
 * Ensure your model was trained on the specific classes you want to classify.
 */
USTRUCT(BlueprintType)
struct FInworldTextClassifierCreationConfig
{
	GENERATED_BODY()

	/** Path to the trained model weights file (e.g., .bin, .onnx, .pt) */
	UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = "Inworld|TextClassifier",
		Meta = (ToolTip = "Path to the trained model weights file (e.g., .bin, .onnx, .pt)"))
	FString ModelWeightsPath;

	/** Classes that the model was trained to classify */
	UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = "Inworld|TextClassifier",
		Meta = (ToolTip = "Classes that the model was trained to classify. Must match the model's training data"))
	TArray<FString> SupportedClasses;
};

/**
 * @struct FInworldTextClassifierNodeCreationConfig
 * @brief Configuration for creating the TextClassifierNode.
 *
 * TextClassifierNodeCreationConfig contains the configuration parameters
 * used at creation time to instantiate the underlying text classifier.
 */
USTRUCT(BlueprintType)
struct FInworldTextClassifierNodeCreationConfig
{
	GENERATED_BODY()

	/** Component ID for the text embedder */
	UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = "Inworld|TextClassifier",
		Meta = (GetOptions = "InworldRuntimeSettings.GetTextEmbedderIds",
			ToolTip = "The ID of the text embedder component to use for text classification"))
	FString EmbedderComponentId{"Default"};

	/** Configuration for the text classifier */
	UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = "Inworld|TextClassifier",
		Meta = (ToolTip = "Configuration for the text classifier including model path and supported classes"))
	FInworldTextClassifierCreationConfig ClassifierConfig;
};

/**
 * @struct FInworldTextClassifierNodeExecutionConfig
 * @brief Runtime configuration for the TextClassifierNode that is used during
 * execution.
 *
 * TextClassifierNodeExecutionConfig contains the configuration parameters that
 * are applied at execution time when the TextClassifierNode processes input.
 * This includes settings for classification thresholds and class selection.
 */
USTRUCT(BlueprintType)
struct FInworldTextClassifierNodeExecutionConfig
{
	GENERATED_BODY()

	/**
	 * @brief Indicates whether a text classifier configuration is present.
	 *
	 * This variable is used to determine if a text classification configuration
	 * is specified, enabling or disabling related functionality.
	 */
	UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = "Inworld|TextClassifier",
		Meta = (ToolTip = "Indicates whether a text classifier configuration is present"))
	bool HasTextClassifierConfig{false};

	/** Configuration for the text classifier */
	UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = "Inworld|TextClassifier",
		Meta = (EditCondition = "HasTextClassifierConfig", EditConditionHides,
			ToolTip = "Configuration for the text classifier including class detection thresholds"))
	FInworldTextClassifierConfig ClassifierConfig{};
};
