"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ExpressionInternalApi = void 0;
const tslib_1 = require("tslib");
const ApiBase_1 = require("../Implementation/ApiBase");
const ArrayExtensions_1 = tslib_1.__importDefault(require("../../Utilities/Extensions/ArrayExtensions"));
class ExpressionInternalApi extends ApiBase_1.ApiBase {
    /**
     * Checks if a column is referenced in a given Expression
     * @param columnId Column to Check
     * @param expression Expression to Lookup
     */
    isColumnReferencedInExpression(columnId, expression) {
        const colIds = this.getExpressionApi().getColumnsFromExpression(expression);
        return colIds.some((c) => c === columnId);
    }
    evaluateExpressionInAdaptableQL(module, object, expression) {
        var _a;
        const evaluateExpressionExternallyFn = (_a = this.getExpressionOptions()) === null || _a === void 0 ? void 0 : _a.evaluateAdaptableQLExternally;
        if (typeof evaluateExpressionExternallyFn !== 'function') {
            return true;
        }
        const context = Object.assign(Object.assign({}, this.getAdaptableInternalApi().buildBaseContext()), { module });
        if (object) {
            context.object = object;
        }
        if (expression) {
            context.expression = expression;
            context.referencedColumns = this.getAdaptableApi()
                .expressionApi.getColumnsFromExpression(expression)
                .map((columnId) => this.getColumnApi().getColumnWithColumnId(columnId));
        }
        return !evaluateExpressionExternallyFn(context);
    }
    evaluatePredicatesInAdaptableQL(module, object, predicates) {
        var _a;
        const evaluateExpressionExternallyFn = (_a = this.getExpressionOptions()) === null || _a === void 0 ? void 0 : _a.evaluateAdaptableQLExternally;
        if (typeof evaluateExpressionExternallyFn !== 'function') {
            return true;
        }
        const context = Object.assign(Object.assign({}, this.getAdaptableInternalApi().buildBaseContext()), { module });
        if (object) {
            context.object = object;
        }
        if (predicates) {
            context.predicates = predicates;
            // need to find a way to get the columns in the predicates
            // cand do later
            //        this.getAdaptableApi().columnScopeApi.getColumnsForScope();
        }
        return !evaluateExpressionExternallyFn(context);
    }
    // Used later, when we extend to support inferring fields from data
    // private getFieldsFromData<T extends Record<string, any>>(data: T): string[] {
    //   if (!data) {
    //     return [];
    //   }
    //   if (typeof data !== 'object' || Number.isNaN(data)) {
    //     return [];
    //   }
    //   const keys: string[] = [];
    //   for (const key in Object.keys(data)) {
    //     const candidate = data[key];
    //     if (
    //       typeof candidate === 'number' ||
    //       typeof candidate === 'string' ||
    //       typeof candidate === 'boolean' ||
    //       candidate instanceof Date
    //     ) {
    //       keys.push(key);
    //       continue;
    //     }
    //     // no support for arrays
    //     // for objects we go one level deep
    //     if (typeof candidate === 'object' && candidate !== null && !Array.isArray(candidate)) {
    //       const childKeys = this.getFieldsFromData(candidate);
    //       for (const childKey of childKeys) {
    //         keys.push(`${key}.${childKey}`);
    //       }
    //     }
    //   }
    //   return keys;
    // }
    getFieldsFromOptions() {
        const fields = this.getExpressionOptions().fields;
        if (fields != null && typeof fields === 'function') {
            return fields(this.getAdaptableInternalApi().buildBaseContext());
        }
        else {
            let arr = fields;
            if (arr && ArrayExtensions_1.default.IsNotNullOrEmpty(arr)) {
                return arr;
            }
        }
    }
    getAvailableFields(data) {
        var _a, _b;
        const optionFields = (_b = ((_a = this.getFieldsFromOptions()) !== null && _a !== void 0 ? _a : [])) === null || _b === void 0 ? void 0 : _b.map((field) => (Object.assign(Object.assign({}, field), { label: field.label || field.name })));
        // const existingFields = new Set<string>();
        // Exclude fields already in options
        // optionFields.forEach((field) => existingFields.add(field.value));
        // const queriableColumns = this.getColumnApi().getQueryableColumns();
        // Exclude queriable columns
        // queriableColumns.forEach((column) => existingFields.add(column.field));
        // const dataFields = this.getFieldsFromData(data).reduce<AdaptableField[]>((acc, field) => {
        //   if (!existingFields.has(field)) {
        //     acc.push({
        //       label: field,
        //       value: field,
        //     });
        //   }
        //   return acc;
        // }, []);
        return optionFields;
    }
    getFieldType(field) {
        var _a;
        const fieldDef = (_a = this.getFieldsFromOptions()) === null || _a === void 0 ? void 0 : _a.find((f) => f.name === field);
        if (fieldDef) {
            return fieldDef.dataType;
        }
        return 'String';
    }
    getFieldsOfType(type) {
        var _a, _b, _c;
        if (!type) {
            return (_a = this.getAvailableFields()) !== null && _a !== void 0 ? _a : [];
        }
        return (_c = (_b = this.getAvailableFields()) === null || _b === void 0 ? void 0 : _b.filter((f) => f.dataType === type)) !== null && _c !== void 0 ? _c : [];
    }
}
exports.ExpressionInternalApi = ExpressionInternalApi;
