/**
 * Formula evaluation utilities for computed fields
 */
/**
 * Evaluate TABLE_SUM function
 * Syntax: TABLE_SUM(table_id, sum_column, filter_column, filter_value)
 * Returns the sum of sum_column values where filter_column equals filter_value
 */
function evaluate_table_sum(args, values) {
    if (args.length !== 4) {
        console.warn("TABLE_SUM requires 4 arguments: table_id, sum_column, filter_column, filter_value");
        return null;
    }
    const [table_id, sum_column, filter_column, filter_value] = args.map(a => a.trim());
    const table_data = values[table_id];
    if (!Array.isArray(table_data)) {
        return null;
    }
    let sum = 0;
    for (const row of table_data) {
        if (typeof row === "object" && row !== null) {
            const row_obj = row;
            const row_filter_value = String(row_obj[filter_column]).toLowerCase();
            const target_filter_value = filter_value.toLowerCase();
            if (row_filter_value === target_filter_value) {
                const val = row_obj[sum_column];
                const num = typeof val === "number" ? val : parseFloat(String(val));
                if (!isNaN(num)) {
                    sum += num;
                }
            }
        }
    }
    return sum;
}
/**
 * Simple arithmetic expression evaluator
 * Only supports: numbers, +, -, *, /, parentheses, whitespace, decimal points
 * This avoids using eval() or new Function() for security
 */
function evaluate_arithmetic(expression) {
    // Validate that expression only contains safe characters
    if (!/^[\d\s+\-*/().]+$/.test(expression)) {
        console.warn("Invalid formula expression:", expression);
        return null;
    }
    // Use Function constructor with validated input - the regex above ensures
    // only digits, arithmetic operators, parentheses, dots, and whitespace
    // are present, making code injection impossible
    try {
        // eslint-disable-next-line no-new-func
        const result = new Function(`return (${expression})`)();
        return typeof result === "number" && !isNaN(result) ? result : null;
    }
    catch {
        return null;
    }
}
/**
 * Safely evaluate a computed formula
 * Supports basic arithmetic operations and TABLE_SUM function
 *
 * Supported functions:
 * - TABLE_SUM(table_id, sum_column, filter_column, filter_value)
 *   Sums values from a table column where another column matches a filter value
 */
export function evaluate_formula(formula, values) {
    try {
        let expression = formula;
        // First, process TABLE_SUM functions
        if (formula.includes("TABLE_SUM")) {
            const table_sum_regex = /TABLE_SUM\s*\(\s*([^,]+)\s*,\s*([^,]+)\s*,\s*([^,]+)\s*,\s*([^)]+)\s*\)/gi;
            expression = expression.replace(table_sum_regex, (_match, table_id, sum_col, filter_col, filter_val) => {
                const result = evaluate_table_sum([table_id, sum_col, filter_col, filter_val], values);
                return result !== null ? String(result) : "0";
            });
        }
        // Find all remaining field references (alphanumeric with underscores)
        const field_refs = expression.match(/[a-zA-Z_][a-zA-Z0-9_]*/g) || [];
        for (const ref of field_refs) {
            if (ref.toUpperCase() === "TABLE_SUM")
                continue;
            const value = values[ref];
            if (typeof value === "number") {
                expression = expression.replace(new RegExp(`\\b${ref}\\b`, "g"), String(value));
            }
            else if (typeof value === "string" && !isNaN(parseFloat(value))) {
                expression = expression.replace(new RegExp(`\\b${ref}\\b`, "g"), value);
            }
            else if (value === undefined || value === null || value === "") {
                expression = expression.replace(new RegExp(`\\b${ref}\\b`, "g"), "0");
            }
            else {
                return null;
            }
        }
        return evaluate_arithmetic(expression);
    }
    catch (error) {
        console.warn("Formula evaluation error:", error);
        return null;
    }
}
//# sourceMappingURL=formula.js.map