"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ColumnFilterInternalApi = void 0;
const tslib_1 = require("tslib");
const ApiBase_1 = require("../Implementation/ApiBase");
const StringExtensions_1 = tslib_1.__importDefault(require("../../Utilities/Extensions/StringExtensions"));
const LayoutRedux = tslib_1.__importStar(require("../../Redux/ActionsReducers/LayoutRedux"));
const ArrayExtensions_1 = tslib_1.__importDefault(require("../../Utilities/Extensions/ArrayExtensions"));
class ColumnFilterInternalApi extends ApiBase_1.ApiBase {
    /**
     * Returns Predicate Definition for given Column and Quick Filter shortcut
     * @param shortcut Quick Filter shortcut to lookup
     * @param column AdapTable Column being Filtered
     */
    findPredicateDefByShortcut(shortcut, column) {
        return this.getColumnFilterApi()
            .getFilterPredicateDefsForColumn(column)
            .find((predicateDef) => { var _a; return (_a = this.getPredicateDefShortcuts(predicateDef)) === null || _a === void 0 ? void 0 : _a.includes(shortcut); });
    }
    /**
     * Creates an Equality Filter based on given Grid Cells
     * @param gridCells cells to create Filter for
     */
    createValuesColumnFilterForCells(gridCells) {
        if (!gridCells) {
            return null;
        }
        const filter = {
            ColumnId: gridCells[0].column.columnId,
            Predicate: {
                PredicateId: 'Values',
                Inputs: [...new Set(gridCells.map((gc) => gc.displayValue))],
            },
        };
        const [savedFilter] = this.getColumnFilterApi().setColumnFilters([filter]) || [null];
        return savedFilter;
    }
    /**
     *  Creates an Equality Filter based on given Grid Cell
     * @param gridCell cell to create Filter for
     */
    createEqualityColumnFilterForCell(gridCell) {
        if (!gridCell) {
            return null;
        }
        const column = gridCell.column;
        const filter = {
            ColumnId: column.columnId,
            Predicate: {
                PredicateId: this.getPredicateApi().internalApi.getEqualityPredicateForDataType(column.dataType),
                Inputs: [...new Set([gridCell.rawValue])],
            },
        };
        const [savedFilter] = this.getColumnFilterApi().setColumnFilters([filter]) || [null];
        return savedFilter;
    }
    /**
     * Retrieves description of given Column Filter
     * @param columnFilter Column Filter to use
     */
    columnFilterToString(columnFilter) {
        const friendlyName = this.getColumnApi().getFriendlyNameForColumnId(columnFilter.ColumnId);
        return ('[' +
            friendlyName +
            '] ' +
            this.getPredicateApi().predicateToString(columnFilter.Predicate));
    }
    /**
     * Retrieves descriptions of given Column Filters
     * @param columnFilters Column Filters to use
     */
    columnFiltersToString(columnFilters) {
        return columnFilters.map((cf) => this.columnFilterToString(cf)).join(', ');
    }
    /**
     * Calls AdapTableQL to evaluate Filter for given Row
     * @param columnFilter Column Filter to use
     * @param node Row Node to evaluate
     */
    evaluateColumnFilter(columnFilter, node) {
        var _a;
        if (!columnFilter.Predicate) {
            return true;
        }
        const someInputsAreEmpty = (_a = columnFilter.Predicate.Inputs) === null || _a === void 0 ? void 0 : _a.some((input) => {
            if (typeof input === 'string') {
                return StringExtensions_1.default.IsNullOrEmpty(input);
            }
            if (typeof input === 'number') {
                return isNaN(input);
            }
            return !input;
        });
        if (someInputsAreEmpty) {
            return true;
        }
        const column = this.getColumnApi().getColumnWithColumnId(columnFilter.ColumnId);
        if (!column) {
            return true;
        }
        const gridCell = this.getGridApi().getGridCellFromRowNode(node, columnFilter.ColumnId);
        if (!gridCell) {
            return true;
        }
        let value = gridCell.normalisedValue;
        const predicateDefHandlerContext = Object.assign({ value: value, oldValue: null, displayValue: gridCell.displayValue, node,
            column }, this.getAdaptableInternalApi().buildBaseContext());
        return this.getPredicateApi().handlePredicate(columnFilter.Predicate, predicateDefHandlerContext, true);
    }
    /**
     * Checks if the filter action should trigger Column Filtering
     *
     * @param action Filtering Action
     */
    shouldNewColumnFilterTriggerColumnFiltering(action) {
        // trigger filter change only:
        // - new -> new filter is active
        // - clear -> previous filters was active
        // - clearAll -> a filter was active
        // - edit -> same => input change
        // - edit -> different & new is active
        // - edit -> different & old was active
        // - set -> new filter is active
        // filter -> suspend changes
        var _a, _b;
        const isNewAndActive = action.type === LayoutRedux.LAYOUT_COLUMN_FILTER_ADD &&
            this.getAdaptableApi().columnFilterApi.isColumnFilterActive(action.columnFilter);
        const isClearAndPreviousWasActive = action.type === LayoutRedux.LAYOUT_COLUMN_FILTER_CLEAR &&
            this.getAdaptableApi().columnFilterApi.isColumnFilterActive(action.columnFilter);
        const isClearAllAtLeastOneActiveFilter = action.type === LayoutRedux.LAYOUT_COLUMN_FILTER_CLEAR_ALL &&
            this.getAdaptableApi()
                .columnFilterApi.getColumnFilters()
                .some((columnFilter) => this.getAdaptableApi().columnFilterApi.isColumnFilterActive(columnFilter));
        let isEditTrigger = false;
        if (action.type === LayoutRedux.LAYOUT_COLUMN_FILTER_EDIT) {
            const newFilter = action.columnFilter;
            const previous = this.getAdaptableApi().columnFilterApi.getColumnFilterForColumn(newFilter.ColumnId);
            // same filter edit, so always trigger
            if (((_a = previous === null || previous === void 0 ? void 0 : previous.Predicate) === null || _a === void 0 ? void 0 : _a.PredicateId) === ((_b = newFilter === null || newFilter === void 0 ? void 0 : newFilter.Predicate) === null || _b === void 0 ? void 0 : _b.PredicateId)) {
                isEditTrigger = true;
                // new filter is active
            }
            else if (this.getAdaptableApi().columnFilterApi.isColumnFilterActive(newFilter)) {
                isEditTrigger = true;
            }
            else if (this.getAdaptableApi().columnFilterApi.isColumnFilterActive(previous)) {
                // previous filter was active
                isEditTrigger = true;
            }
        }
        const isSetAndActive = action.type === LayoutRedux.LAYOUT_COLUMN_FILTER_SET &&
            this.getAdaptableApi().columnFilterApi.isColumnFilterActive(action.columnFilter);
        const isSuspendChanged = [
            LayoutRedux.LAYOUT_COLUMN_FILTER_SUSPEND,
            LayoutRedux.LAYOUT_COLUMN_FILTER_SUSPEND_ALL,
            LayoutRedux.LAYOUT_COLUMN_FILTER_UNSUSPEND,
            LayoutRedux.LAYOUT_COLUMN_FILTER_UNSUSPEND_ALL,
        ].includes(action.type);
        return (isNewAndActive ||
            isClearAndPreviousWasActive ||
            isClearAllAtLeastOneActiveFilter ||
            isEditTrigger ||
            isSetAndActive ||
            isSuspendChanged);
    }
    /**
     * Fires Column Filter Applied Event - typically used to enable filtering on the server
     */
    fireColumnFilterAppliedEvent() {
        if (this.isAdapTableReady()) {
            const columnFilterAppliedInfo = Object.assign({ columnFilters: this.getColumnFilterApi().getColumnFilters() }, this.getAdaptableInternalApi().buildBaseContext());
            this.getEventApi().emit('ColumnFilterApplied', columnFilterAppliedInfo);
        }
    }
    fireGridFilterAppliedEvent() {
        if (this.isAdapTableReady()) {
            const gridFilterAppliedInfo = Object.assign({ columnFilters: this.getColumnFilterApi().getColumnFilters() }, this.getAdaptableInternalApi().buildBaseContext());
            this.getEventApi().emit('GridFilterApplied', gridFilterAppliedInfo);
        }
    }
    /**
     * Compares to sets of Column Filters to see if they are identical
     * @param filters1
     * @param filters2
     */
    areColumnFiltersDifferent(oldFilters, newFilters) {
        if (ArrayExtensions_1.default.IsNullOrEmpty(oldFilters) && ArrayExtensions_1.default.IsNullOrEmpty(newFilters)) {
            return false;
        }
        return ArrayExtensions_1.default.areArraysNotEqual(oldFilters, newFilters);
    }
    getPredicateDefShortcuts(predicateDef) {
        const shortcuts = this.getColumnFilterOptions().quickFilterOptions.quickFilterWildcards;
        let predicateShortcuts = predicateDef.shortcuts;
        const predicateId = predicateDef.id;
        if ((shortcuts === null || shortcuts === void 0 ? void 0 : shortcuts[predicateId]) && Array.isArray(shortcuts[predicateId])) {
            predicateShortcuts = shortcuts[predicateId];
        }
        return predicateShortcuts;
    }
    getFilterValuesMaxNumberOfItems(column) {
        const maxFilterValues = this.getColumnFilterOptions().valuesFilterOptions.maxFilterValuesToDisplay;
        if (typeof maxFilterValues === 'function') {
            const columnFilterContext = Object.assign(Object.assign({}, this.getAdaptableInternalApi().buildBaseContext()), { column: column });
            return maxFilterValues(columnFilterContext);
        }
        else {
            return maxFilterValues;
        }
    }
    getValuesFitlerPredicateIds(column) {
        var _a, _b;
        const valuesFilterPredicateOptions = (_b = (_a = this.getOptions().columnFilterOptions) === null || _a === void 0 ? void 0 : _a.valuesFilterOptions) === null || _b === void 0 ? void 0 : _b.valuesFilterPredicateOptions;
        const availablePredicates = this.getPredicateApi().getPredicateDefsByModuleScope('columnFilter');
        let predicateIds = [];
        if (typeof (valuesFilterPredicateOptions === null || valuesFilterPredicateOptions === void 0 ? void 0 : valuesFilterPredicateOptions.predicates) === 'function') {
            const columnFilterContext = Object.assign(Object.assign({}, this.getAdaptableInternalApi().buildBaseContext()), { column: column });
            predicateIds = valuesFilterPredicateOptions.predicates(columnFilterContext);
        }
        else if (Array.isArray(valuesFilterPredicateOptions === null || valuesFilterPredicateOptions === void 0 ? void 0 : valuesFilterPredicateOptions.predicates)) {
            predicateIds = valuesFilterPredicateOptions.predicates;
        }
        return predicateIds.filter((predicateId) => {
            const predicate = availablePredicates.find((p) => p.id === predicateId);
            if (!predicate) {
                return false;
            }
            return this.getColumnScopeApi().isColumnInScope(column, predicate.columnScope);
        });
    }
}
exports.ColumnFilterInternalApi = ColumnFilterInternalApi;
