package workflow

import (
	"encoding/json"
	"fmt"
	"reflect"
	"strconv"
	"strings"
)

// ExpressionEvaluator evaluates workflow expressions.
type ExpressionEvaluator struct {
	context ContextAccessor
}

// NewExpressionEvaluator creates a new expression evaluator
func NewExpressionEvaluator(ctx ContextAccessor) *ExpressionEvaluator {
	return &ExpressionEvaluator{
		context: ctx,
	}
}

// EvaluateValue evaluates an arbitrary JSON value using the = prefix convention:
//   - Non-string types (bool, number, etc.): returned as-is (literal value)
//   - String not starting with "=": returned as literal string
//   - String starting with "=": remainder evaluated as expression (e.g. "=$name")
//   - String starting with "==": leading "=" removed, rest returned as literal string (e.g. "==foo" → "=foo")
func (e *ExpressionEvaluator) EvaluateValue(value interface{}) (interface{}, error) {
	str, ok := value.(string)
	if !ok {
		// Non-string types are literal values
		return value, nil
	}

	if !strings.HasPrefix(str, "=") {
		// No = prefix: literal string
		return str, nil
	}

	if strings.HasPrefix(str, "==") {
		// == prefix: escaped literal, strip one leading =
		return str[1:], nil
	}

	// Single = prefix: evaluate the rest as expression
	return e.Evaluate(str[1:])
}

// Evaluate evaluates an expression string and returns the result
func (e *ExpressionEvaluator) Evaluate(expr string) (interface{}, error) {
	if expr == "" {
		return nil, nil
	}

	expr = strings.TrimSpace(expr)

	// Handle string literals (must be a simple quoted string, not a complex expression)
	if isSimpleStringLiteral(expr) {
		return expr[1 : len(expr)-1], nil
	}

	// Handle boolean literals
	if expr == "true" {
		return true, nil
	}
	if expr == "false" {
		return false, nil
	}

	// Handle null/nil
	if expr == "null" || expr == "nil" {
		return nil, nil
	}

	// Handle numeric literals
	if num, err := strconv.ParseInt(expr, 10, 64); err == nil {
		return num, nil
	}
	if num, err := strconv.ParseFloat(expr, 64); err == nil {
		return num, nil
	}

	// Handle JSON literal arrays and objects
	if strings.HasPrefix(expr, "[") || strings.HasPrefix(expr, "{") {
		var parsed interface{}
		if err := json.Unmarshal([]byte(expr), &parsed); err == nil {
			return parsed, nil
		}
	}

	// Handle logical operators (check before comparison operators)
	if strings.Contains(expr, "&&") {
		return e.evaluateLogicalAnd(expr)
	}
	if strings.Contains(expr, "||") {
		return e.evaluateLogicalOr(expr)
	}

	// Handle comparison operators (check before variable references)
	if strings.Contains(expr, "==") {
		return e.evaluateBinaryOp(expr, "==")
	}
	if strings.Contains(expr, "!=") {
		return e.evaluateBinaryOp(expr, "!=")
	}
	if strings.Contains(expr, ">=") {
		return e.evaluateBinaryOp(expr, ">=")
	}
	if strings.Contains(expr, "<=") {
		return e.evaluateBinaryOp(expr, "<=")
	}
	if strings.Contains(expr, ">") {
		return e.evaluateBinaryOp(expr, ">")
	}
	if strings.Contains(expr, "<") {
		return e.evaluateBinaryOp(expr, "<")
	}

	// Handle negation
	if strings.HasPrefix(expr, "!") {
		val, err := e.Evaluate(strings.TrimSpace(expr[1:]))
		if err != nil {
			return nil, err
		}
		return !toBool(val), nil
	}

	// Handle arithmetic operators
	if e.findOperatorIndex(expr, "+") != -1 {
		return e.evaluateArithmetic(expr, "+")
	}
	if e.findOperatorIndex(expr, "-") != -1 && !e.isSimpleNegativeNumber(expr) {
		return e.evaluateArithmetic(expr, "-")
	}
	if strings.Contains(expr, "*") {
		return e.evaluateArithmetic(expr, "*")
	}
	if strings.Contains(expr, "/") {
		return e.evaluateArithmetic(expr, "/")
	}

	// Handle variable references
	if strings.HasPrefix(expr, "$") || strings.HasPrefix(expr, "_") || strings.HasPrefix(expr, "SYSVAR.") {
		return e.evaluateVariableReference(expr)
	}

	// Try to resolve as a path (could be param reference or variable reference)
	return e.evaluateVariableReference(expr)
}

// isSimpleStringLiteral checks if expr is a simple quoted string (not a complex expression)
func isSimpleStringLiteral(expr string) bool {
	if len(expr) < 2 {
		return false
	}
	quote := expr[0]
	if quote != '"' && quote != '\'' {
		return false
	}
	if expr[len(expr)-1] != quote {
		return false
	}
	// Check that there are no unescaped quotes in the middle
	for i := 1; i < len(expr)-1; i++ {
		if expr[i] == quote && (i == 0 || expr[i-1] != '\\') {
			return false
		}
	}
	return true
}

// isSimpleNegativeNumber checks if expr is just a negative number like "-5"
func (e *ExpressionEvaluator) isSimpleNegativeNumber(expr string) bool {
	if !strings.HasPrefix(expr, "-") {
		return false
	}
	rest := strings.TrimSpace(expr[1:])
	if _, err := strconv.ParseInt(rest, 10, 64); err == nil {
		return true
	}
	if _, err := strconv.ParseFloat(rest, 64); err == nil {
		return true
	}
	return false
}

// evaluateVariableReference resolves variable references and paths
func (e *ExpressionEvaluator) evaluateVariableReference(path string) (interface{}, error) {
	parts := e.parsePath(path)
	if len(parts) == 0 {
		return nil, fmt.Errorf("empty variable path")
	}

	// Get the root variable
	var root interface{}
	var err error
	startIndex := 1

	rootName := parts[0]

	if strings.HasPrefix(rootName, "$") {
		// Global variable
		root, err = e.getGlobalVariable(rootName)
	} else if rootName == "SYSVAR" {
		// System variable - combine SYSVAR with next part for lookup
		if len(parts) < 2 {
			return nil, fmt.Errorf("incomplete SYSVAR reference")
		}
		sysvarKey := "SYSVAR." + parts[1]
		root, err = e.getSystemVariable(sysvarKey)
		startIndex = 2
	} else if strings.HasPrefix(rootName, "_") {
		// Local variable
		root, err = e.getLocalVariable(rootName)
	} else {
		// Try as parameter reference
		root, err = e.getParameter(rootName)
		if err != nil {
			return nil, err
		}
	}

	if err != nil {
		return nil, err
	}

	// Navigate the path
	current := root
	for i := startIndex; i < len(parts); i++ {
		part := parts[i]
		current, err = e.navigatePath(current, part)
		if err != nil {
			return nil, err
		}
	}

	return current, nil
}

// parsePath parses a variable path into segments
// Handles: $var.field, $var[index], $var["literal"], SYSVAR.xxx
func (e *ExpressionEvaluator) parsePath(path string) []string {
	var parts []string
	current := ""
	inBracket := false
	bracketContent := ""

	for i := 0; i < len(path); i++ {
		ch := path[i]

		switch ch {
		case '.':
			if inBracket {
				bracketContent += string(ch)
			} else {
				if current != "" {
					parts = append(parts, current)
					current = ""
				}
			}
		case '[':
			if current != "" {
				parts = append(parts, current)
				current = ""
			}
			inBracket = true
			bracketContent = ""
		case ']':
			if inBracket {
				// Evaluate bracket content as expression
				val, err := e.Evaluate(bracketContent)
				if err == nil {
					parts = append(parts, fmt.Sprintf("[%v]", val))
				}
				inBracket = false
				bracketContent = ""
			}
		default:
			if inBracket {
				bracketContent += string(ch)
			} else {
				current += string(ch)
			}
		}
	}

	if current != "" {
		parts = append(parts, current)
	}

	return parts
}

// navigatePath navigates one level in a nested structure
func (e *ExpressionEvaluator) navigatePath(obj interface{}, key string) (interface{}, error) {
	if obj == nil {
		return nil, fmt.Errorf("cannot navigate path on nil object")
	}

	// Handle .length property on arrays, slices, and strings
	if key == "length" {
		val := reflect.ValueOf(obj)
		switch val.Kind() {
		case reflect.Slice, reflect.Array:
			return int64(val.Len()), nil
		case reflect.String:
			// Return the number of Unicode code points (runes), not bytes
			return int64(len([]rune(val.String()))), nil
		}
		// Fall through to map lookup so user-defined "length" keys still work
	}

	// Handle array/slice index: [index]
	if strings.HasPrefix(key, "[") && strings.HasSuffix(key, "]") {
		indexStr := key[1 : len(key)-1]
		index, err := strconv.Atoi(indexStr)
		if err != nil {
			return nil, fmt.Errorf("invalid array index: %s", indexStr)
		}

		val := reflect.ValueOf(obj)
		if val.Kind() == reflect.Slice || val.Kind() == reflect.Array {
			if index < 0 || index >= val.Len() {
				return nil, fmt.Errorf("index out of range: %d", index)
			}
			return val.Index(index).Interface(), nil
		}
		return nil, fmt.Errorf("cannot index non-array type")
	}

	// Handle map/struct field access
	val := reflect.ValueOf(obj)

	if val.Kind() == reflect.Map {
		mapVal := val.MapIndex(reflect.ValueOf(key))
		if mapVal.IsValid() {
			return mapVal.Interface(), nil
		}
		return nil, nil
	}

	if val.Kind() == reflect.Struct {
		field := val.FieldByName(key)
		if field.IsValid() {
			return field.Interface(), nil
		}
		return nil, fmt.Errorf("field not found: %s", key)
	}

	return nil, fmt.Errorf("cannot access field on type: %T", obj)
}

// getParameter retrieves a parameter
func (e *ExpressionEvaluator) getParameter(name string) (interface{}, error) {
	if val, ok := e.context.GetParam(name); ok {
		return val, nil
	}
	return nil, fmt.Errorf("parameter not found: %s", name)
}

// getGlobalVariable retrieves a global variable
func (e *ExpressionEvaluator) getGlobalVariable(name string) (interface{}, error) {
	if val, ok := e.context.GetVariable(name); ok {
		return val, nil
	}
	return nil, nil // Undefined variables return nil
}

// getSystemVariable retrieves a system variable
func (e *ExpressionEvaluator) getSystemVariable(name string) (interface{}, error) {
	if val, ok := e.context.GetSystemVar(name); ok {
		return val, nil
	}
	return nil, fmt.Errorf("system variable not found: %s", name)
}

// getLocalVariable retrieves a local variable
func (e *ExpressionEvaluator) getLocalVariable(name string) (interface{}, error) {
	if val, ok := e.context.GetLocalVar(name); ok {
		return val, nil
	}
	return nil, fmt.Errorf("local variable not found: %s", name)
}

// evaluateBinaryOp evaluates binary comparison operations
func (e *ExpressionEvaluator) evaluateBinaryOp(expr string, op string) (interface{}, error) {
	parts := strings.SplitN(expr, op, 2)
	if len(parts) != 2 {
		return nil, fmt.Errorf("invalid binary operation: %s", expr)
	}

	left, err := e.Evaluate(strings.TrimSpace(parts[0]))
	if err != nil {
		return nil, err
	}

	right, err := e.Evaluate(strings.TrimSpace(parts[1]))
	if err != nil {
		return nil, err
	}

	return e.compare(left, right, op)
}

// compare compares two values based on the operator
func (e *ExpressionEvaluator) compare(left, right interface{}, op string) (bool, error) {
	switch op {
	case "==":
		return e.equals(left, right), nil
	case "!=":
		return !e.equals(left, right), nil
	case ">", ">=", "<", "<=":
		return e.compareNumeric(left, right, op)
	default:
		return false, fmt.Errorf("unknown operator: %s", op)
	}
}

// equals compares two values for equality, normalizing numeric types
func (e *ExpressionEvaluator) equals(left, right interface{}) bool {
	// Handle nil cases
	if left == nil && right == nil {
		return true
	}
	if left == nil || right == nil {
		return false
	}

	// Normalize numeric types for comparison
	if isNumeric(left) && isNumeric(right) {
		return toFloat64(left) == toFloat64(right)
	}

	return reflect.DeepEqual(left, right)
}

func isNumeric(val interface{}) bool {
	switch val.(type) {
	case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, float32, float64:
		return true
	default:
		return false
	}
}

// compareNumeric compares numeric values
func (e *ExpressionEvaluator) compareNumeric(left, right interface{}, op string) (bool, error) {
	l := toFloat64(left)
	r := toFloat64(right)

	switch op {
	case ">":
		return l > r, nil
	case ">=":
		return l >= r, nil
	case "<":
		return l < r, nil
	case "<=":
		return l <= r, nil
	default:
		return false, fmt.Errorf("unknown numeric operator: %s", op)
	}
}

// evaluateLogicalAnd evaluates logical AND
func (e *ExpressionEvaluator) evaluateLogicalAnd(expr string) (interface{}, error) {
	parts := strings.Split(expr, "&&")
	for _, part := range parts {
		val, err := e.Evaluate(strings.TrimSpace(part))
		if err != nil {
			return nil, err
		}
		if !toBool(val) {
			return false, nil
		}
	}
	return true, nil
}

// evaluateLogicalOr evaluates logical OR
func (e *ExpressionEvaluator) evaluateLogicalOr(expr string) (interface{}, error) {
	parts := strings.Split(expr, "||")
	for _, part := range parts {
		val, err := e.Evaluate(strings.TrimSpace(part))
		if err != nil {
			return nil, err
		}
		if toBool(val) {
			return true, nil
		}
	}
	return false, nil
}

// evaluateArithmetic evaluates arithmetic operations
func (e *ExpressionEvaluator) evaluateArithmetic(expr string, op string) (interface{}, error) {
	// Find the operator (avoiding string literals)
	opIndex := e.findOperatorIndex(expr, op)
	if opIndex == -1 {
		return nil, fmt.Errorf("operator not found: %s", op)
	}

	leftExpr := strings.TrimSpace(expr[:opIndex])
	rightExpr := strings.TrimSpace(expr[opIndex+len(op):])

	left, err := e.Evaluate(leftExpr)
	if err != nil {
		return nil, err
	}

	right, err := e.Evaluate(rightExpr)
	if err != nil {
		return nil, err
	}

	// Handle string concatenation with +
	if op == "+" {
		if isString(left) || isString(right) {
			return toString(left) + toString(right), nil
		}
	}

	// Numeric operations
	l := toFloat64(left)
	r := toFloat64(right)

	switch op {
	case "+":
		return l + r, nil
	case "-":
		return l - r, nil
	case "*":
		return l * r, nil
	case "/":
		if r == 0 {
			return nil, fmt.Errorf("division by zero")
		}
		return l / r, nil
	default:
		return nil, fmt.Errorf("unknown arithmetic operator: %s", op)
	}
}

// findOperatorIndex finds the index of an operator, avoiding string literals
func (e *ExpressionEvaluator) findOperatorIndex(expr string, op string) int {
	inString := false
	stringChar := rune(0)

	for i := 0; i < len(expr)-len(op)+1; i++ {
		ch := rune(expr[i])

		if ch == '"' || ch == '\'' {
			if !inString {
				inString = true
				stringChar = ch
			} else if ch == stringChar {
				inString = false
			}
		}

		if !inString && strings.HasPrefix(expr[i:], op) {
			return i
		}
	}

	return -1
}

// Helper functions

func toBool(val interface{}) bool {
	if val == nil {
		return false
	}
	switch v := val.(type) {
	case bool:
		return v
	case int, int64, float64:
		return toFloat64(v) != 0
	case string:
		return v != ""
	default:
		return true
	}
}

func toFloat64(val interface{}) float64 {
	if val == nil {
		return 0
	}
	switch v := val.(type) {
	case int:
		return float64(v)
	case int64:
		return float64(v)
	case float64:
		return v
	case float32:
		return float64(v)
	case string:
		f, _ := strconv.ParseFloat(v, 64)
		return f
	default:
		return 0
	}
}

func toString(val interface{}) string {
	if val == nil {
		return ""
	}
	return fmt.Sprintf("%v", val)
}

func isString(val interface{}) bool {
	_, ok := val.(string)
	return ok
}

// SetVariable sets a variable value using a path expression
func (e *ExpressionEvaluator) SetVariable(path string, value interface{}) error {
	parts := e.parsePath(path)
	if len(parts) == 0 {
		return fmt.Errorf("empty variable path")
	}

	rootName := parts[0]

	// Check if trying to set a parameter (read-only)
	if !strings.HasPrefix(rootName, "$") && !strings.HasPrefix(rootName, "_") {
		// This is a parameter reference - check if it exists
		if _, ok := e.context.GetParam(rootName); ok {
			return fmt.Errorf("cannot modify parameter: %s (parameters are read-only)", rootName)
		}
	}

	// Simple case: direct assignment
	if len(parts) == 1 {
		if strings.HasPrefix(rootName, "$") {
			// Apply type conversion if needed
			convertedValue, err := e.applyTypeConversion(rootName, value)
			if err != nil {
				return err
			}
			e.context.SetVariable(rootName, convertedValue)
			return nil
		}
		return fmt.Errorf("cannot set non-global variable: %s", rootName)
	}

	// Special case: $var[index] - direct slice index assignment with auto-grow
	if len(parts) == 2 && strings.HasPrefix(rootName, "$") {
		lastKey := parts[1]
		if strings.HasPrefix(lastKey, "[") && strings.HasSuffix(lastKey, "]") {
			indexStr := lastKey[1 : len(lastKey)-1]
			index, err := strconv.Atoi(indexStr)
			if err == nil {
				// Use atomic SetArrayIndex to avoid race conditions
				e.context.SetArrayIndex(rootName, index, value)
				return nil
			}
		}
	}

	// Deep set with auto-creation of intermediates
	if !strings.HasPrefix(rootName, "$") {
		return fmt.Errorf("cannot set non-global variable: %s", rootName)
	}

	root, _ := e.context.GetVariable(rootName)
	if root == nil {
		// Auto-create root: slice if next part is [N], map otherwise
		if isArrayIndex(parts[1]) {
			root = make([]interface{}, 0)
		} else {
			root = make(map[string]interface{})
		}
		e.context.SetVariable(rootName, root)
	}

	// Navigate to parent of the final field, auto-creating intermediates.
	// We track (parent, key) so we can propagate slice growth back up.
	current := root
	for i := 1; i < len(parts)-1; i++ {
		key := parts[i]
		// Determine what type the next level should be
		nextIsArray := i+1 < len(parts) && isArrayIndex(parts[i+1])

		if isArrayIndex(key) {
			idx, _ := strconv.Atoi(key[1 : len(key)-1])
			slice, ok := current.([]interface{})
			if !ok {
				return fmt.Errorf("cannot index non-array type %T at path segment %s", current, key)
			}
			// Auto-grow slice
			if idx >= len(slice) {
				grown := make([]interface{}, idx+1)
				copy(grown, slice)
				slice = grown
				// Propagate grown slice back: if root level, update variable
				if i == 1 {
					e.context.SetVariable(rootName, slice)
				}
			}
			// Auto-create element if nil
			if slice[idx] == nil {
				if nextIsArray {
					slice[idx] = make([]interface{}, 0)
				} else {
					slice[idx] = make(map[string]interface{})
				}
			}
			current = slice[idx]
		} else {
			m, ok := current.(map[string]interface{})
			if !ok {
				return fmt.Errorf("cannot access field %s on type %T", key, current)
			}
			if m[key] == nil {
				if nextIsArray {
					m[key] = make([]interface{}, 0)
				} else {
					m[key] = make(map[string]interface{})
				}
			}
			current = m[key]
		}
	}

	// Set the final field
	lastKey := parts[len(parts)-1]
	return e.setField(current, lastKey, value)
}

// setField sets a field on an object
func (e *ExpressionEvaluator) setField(obj interface{}, key string, value interface{}) error {
	if obj == nil {
		return fmt.Errorf("cannot set field on nil object")
	}

	// Handle map
	if m, ok := obj.(map[string]interface{}); ok {
		m[key] = value
		return nil
	}

	// Handle slice index assignment (key is "[N]" format)
	if strings.HasPrefix(key, "[") && strings.HasSuffix(key, "]") {
		indexStr := key[1 : len(key)-1]
		index, err := strconv.Atoi(indexStr)
		if err != nil {
			return fmt.Errorf("invalid array index: %s", indexStr)
		}

		rv := reflect.ValueOf(obj)
		if rv.Kind() == reflect.Slice {
			// Grow slice if necessary
			if index >= rv.Len() {
				// We need to get the pointer to the slice in the parent to grow it
				// For now, return an error if index is out of bounds
				return fmt.Errorf("array index %d out of bounds (length %d)", index, rv.Len())
			}
			rv.Index(index).Set(reflect.ValueOf(value))
			return nil
		}
	}

	return fmt.Errorf("cannot set field on type: %T", obj)
}

// isArrayIndex returns true if the path segment is an array index like "[0]", "[2]"
func isArrayIndex(segment string) bool {
	return strings.HasPrefix(segment, "[") && strings.HasSuffix(segment, "]")
}

// EvaluateDeep recursively evaluates expressions in nested structures (maps, arrays)
// It walks through the entire structure and evaluates any string values that look like expressions
func (e *ExpressionEvaluator) EvaluateDeep(value interface{}) (interface{}, error) {
	switch v := value.(type) {
	case string:
		// Evaluate string values using EvaluateValue (handles = prefix convention)
		return e.EvaluateValue(v)
	case map[string]interface{}:
		// Recursively evaluate all values in the map
		result := make(map[string]interface{})
		for key, val := range v {
			evaluated, err := e.EvaluateDeep(val)
			if err != nil {
				return nil, fmt.Errorf("failed to evaluate map key %s: %w", key, err)
			}
			result[key] = evaluated
		}
		return result, nil
	case []interface{}:
		// Recursively evaluate all elements in the array
		result := make([]interface{}, len(v))
		for i, val := range v {
			evaluated, err := e.EvaluateDeep(val)
			if err != nil {
				return nil, fmt.Errorf("failed to evaluate array index %d: %w", i, err)
			}
			result[i] = evaluated
		}
		return result, nil
	default:
		// For other types (int, bool, float, etc.), return as-is
		return value, nil
	}
}

// applyTypeConversion applies type conversion based on variable type declaration
// If the variable is declared as OBJECT and the value is a string, it parses the string as JSON
// If the variable is declared as an array type (e.g., [OBJECT], [STRING]) and the value is a string, it parses as JSON array
// If the variable is declared as STRING and the value is not a string, it marshals the value to JSON
func (e *ExpressionEvaluator) applyTypeConversion(varName string, value interface{}) (interface{}, error) {
	// Get base context to access VarTypes
	baseCtx := e.context.GetBaseContext()
	if baseCtx.VarTypes == nil {
		return value, nil
	}

	// Check if variable has a type declaration
	varType, ok := baseCtx.VarTypes[varName]
	if !ok {
		return value, nil
	}

	// Check if type is an array type like [OBJECT], [STRING], etc.
	if strings.HasPrefix(varType, "[") && strings.HasSuffix(varType, "]") {
		// Array type
		if str, ok := value.(string); ok {
			var result []interface{}
			if err := json.Unmarshal([]byte(str), &result); err != nil {
				return nil, fmt.Errorf("failed to convert string to %s for variable %s (original string: %q): %w", varType, varName, str, err)
			}
			return result, nil
		}
	} else if varType == "OBJECT" {
		// If type is OBJECT and value is string, parse as JSON
		if str, ok := value.(string); ok {
			var result map[string]interface{}
			if err := json.Unmarshal([]byte(str), &result); err != nil {
				return nil, fmt.Errorf("failed to convert string to OBJECT for variable %s (original string: %q): %w", varName, str, err)
			}
			return result, nil
		}
	} else if varType == "INT" {
		// If type is INT and value is a string, parse as integer
		if str, ok := value.(string); ok {
			if n, err := strconv.ParseInt(str, 10, 64); err == nil {
				return n, nil
			}
			// Also try parsing as float then truncating
			if f, err := strconv.ParseFloat(str, 64); err == nil {
				return int64(f), nil
			}
			return nil, fmt.Errorf("failed to convert string %q to INT for variable %s", str, varName)
		}
		// If value is float64, convert to int64
		if f, ok := value.(float64); ok {
			return int64(f), nil
		}
	} else if varType == "FLOAT" {
		// If type is FLOAT and value is a string, parse as float
		if str, ok := value.(string); ok {
			if f, err := strconv.ParseFloat(str, 64); err == nil {
				return f, nil
			}
			return nil, fmt.Errorf("failed to convert string %q to FLOAT for variable %s", str, varName)
		}
		// If value is int64, convert to float64
		if n, ok := value.(int64); ok {
			return float64(n), nil
		}
	} else if varType == "STRING" {
		// If type is STRING and value is not a string, marshal to JSON
		if _, ok := value.(string); !ok {
			// For non-string values (objects, arrays, etc.), marshal to JSON string
			jsonBytes, err := json.Marshal(value)
			if err != nil {
				return nil, fmt.Errorf("failed to convert %T to STRING for variable %s: %w", value, varName, err)
			}
			return string(jsonBytes), nil
		}
	}

	return value, nil
}
