"use strict";

Object.defineProperty(exports, "__esModule", {
    value: !0
}), exports.FilterPlugin = void 0;

const vtable_1 = require("@visactor/vtable"), filter_engine_1 = require("./filter-engine"), filter_state_manager_1 = require("./filter-state-manager"), filter_toolbar_1 = require("./filter-toolbar"), types_1 = require("./types"), styles_1 = require("./styles"), lodash_1 = require("lodash"), constants_1 = require("./constants");

class FilterPlugin {
    constructor(pluginOptions) {
        var _a, _b, _c, _d;
        this.id = "filter", this.name = "Filter", this.runTime = [ vtable_1.TABLE_EVENT_TYPE.BEFORE_INIT, vtable_1.TABLE_EVENT_TYPE.BEFORE_UPDATE_OPTION, vtable_1.TABLE_EVENT_TYPE.ICON_CLICK, vtable_1.TABLE_EVENT_TYPE.SCROLL ], 
        this.id = null !== (_a = null == pluginOptions ? void 0 : pluginOptions.id) && void 0 !== _a ? _a : this.id, 
        this.pluginOptions = pluginOptions, this.pluginOptions.filterIcon = null !== (_b = pluginOptions.filterIcon) && void 0 !== _b ? _b : {
            name: "filter-icon",
            type: "svg",
            width: 12,
            height: 12,
            positionType: vtable_1.TYPES.IconPosition.right,
            cursor: "pointer",
            svg: '<svg t="1752821809070" class="icon" viewBox="0 0 1664 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="12092" width="200" height="200"><path d="M89.6 179.2A89.6 89.6 0 0 1 89.6 0h1408a89.6 89.6 0 0 1 0 179.2H89.6z m256 384a89.6 89.6 0 0 1 0-179.2h896a89.6 89.6 0 0 1 0 179.2h-896z m256 384a89.6 89.6 0 0 1 0-179.2h384a89.6 89.6 0 0 1 0 179.2h-384z" fill="#93a2b9" p-id="12093"></path></svg>'
        }, this.pluginOptions.filteringIcon = null !== (_c = pluginOptions.filteringIcon) && void 0 !== _c ? _c : {
            name: "filtering-icon",
            type: "svg",
            width: 12,
            height: 12,
            positionType: vtable_1.TYPES.IconPosition.right,
            cursor: "pointer",
            svg: '<svg t="1752821771292" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="11926" width="200" height="200"><path d="M971.614323 53.05548L655.77935 412.054233C635.196622 435.434613 623.906096 465.509377 623.906096 496.583302v495.384307c0 28.975686-35.570152 43.063864-55.353551 21.781723l-159.865852-171.256294c-5.495389-5.895053-8.59279-13.688514-8.592789-21.781722V496.583302c0-31.073925-11.290526-61.148688-31.873254-84.429153L52.385677 53.05548C34.200936 32.472751 48.888611 0 76.365554 0h871.268892c27.476943 0 42.164618 32.472751 23.979877 53.05548z" fill="#416eff" p-id="11927"></path></svg>'
        }, this.pluginOptions.filterModes && this.pluginOptions.filterModes.length || (this.pluginOptions.filterModes = [ "byValue", "byCondition" ]), 
        this.pluginOptions.styles = (0, lodash_1.merge)({}, styles_1.filterStyles, pluginOptions.styles), 
        this.pluginOptions.conditionCategories = null !== (_d = pluginOptions.conditionCategories) && void 0 !== _d ? _d : constants_1.categories;
    }
    initFilterPlugin(eventArgs) {
        this.filterEngine = new filter_engine_1.FilterEngine, this.filterStateManager = new filter_state_manager_1.FilterStateManager(this.table, this.filterEngine), 
        this.filterToolbar = new filter_toolbar_1.FilterToolbar(this.table, this.filterStateManager, this.pluginOptions), 
        this.columns = eventArgs.options.columns, this.filterToolbar.render(document.body), 
        this.updateFilterIcons(this.columns), this.filterStateManager.subscribe(((_, action) => {
            (null == action ? void 0 : action.type) !== types_1.FilterActionType.ADD_FILTER && (this.updateFilterIcons(this.columns), 
            this.table.updateColumns(this.columns, {
                clearRowHeightCache: !1
            }));
        }));
    }
    run(...args) {
        var _a, _b, _c, _d, _e;
        const eventArgs = args[0], runtime = args[1], table = args[2];
        if (this.table = table, runtime === vtable_1.TABLE_EVENT_TYPE.BEFORE_INIT) this.initFilterPlugin(eventArgs); else if (runtime === vtable_1.TABLE_EVENT_TYPE.BEFORE_UPDATE_OPTION) this.filterEngine && this.filterStateManager && this.filterToolbar || this.initFilterPlugin(eventArgs), 
        this.pluginOptions = Object.assign(Object.assign({}, this.pluginOptions), null === (_b = null === (_a = eventArgs.options.plugins) || void 0 === _a ? void 0 : _a.find((plugin => plugin.id === this.id))) || void 0 === _b ? void 0 : _b.pluginOptions), 
        this.columns = eventArgs.options.columns, this.handleOptionUpdate(eventArgs.options); else if (runtime === vtable_1.TABLE_EVENT_TYPE.ICON_CLICK && "filter-icon" === eventArgs.name || "filtering-icon" === eventArgs.name) {
            if (3 === (null === (_c = eventArgs.event) || void 0 === _c ? void 0 : _c.which) || 2 === (null === (_d = eventArgs.event) || void 0 === _d ? void 0 : _d.button) || 2 == (2 & (null === (_e = eventArgs.event) || void 0 === _e ? void 0 : _e.buttons))) return;
            const col = eventArgs.col, row = eventArgs.row;
            this.filterToolbar.isVisible ? this.filterToolbar.hide(eventArgs.col, eventArgs.row) : this.filterToolbar.show(col, row, this.pluginOptions.filterModes);
        } else runtime === vtable_1.TABLE_EVENT_TYPE.SCROLL && "horizontal" === eventArgs.scrollDirection && this.filterToolbar.adjustMenuPosition();
    }
    updatePluginOptions(pluginOptions) {
        this.pluginOptions = (0, lodash_1.merge)(this.pluginOptions, pluginOptions), this.filterToolbar.updatePluginOptions(this.pluginOptions);
    }
    update() {
        if (this.filterToolbar.valueFilter) {
            const allFields = this.table.columns.map((col => col.field)), valueFilter = this.filterToolbar.valueFilter;
            allFields.forEach((field => {
                valueFilter.collectUniqueColumnValues(field, !0);
            })), valueFilter.updateUI(this.filterStateManager.getFilterState(this.filterToolbar.selectedField));
        }
        this.filterStateManager && this.reapplyActiveFilters();
    }
    handleOptionUpdate(options) {
        const currentActiveFields = this.filterStateManager ? this.filterStateManager.getActiveFilterFields() : [];
        this.filterStateManager && currentActiveFields.length > 0 && this.validateFilterStatesAfterUpdate(options, currentActiveFields), 
        this.updateFilterIcons(options.columns);
    }
    reapplyActiveFilters() {
        this.filterStateManager.reapplyCurrentFilters();
    }
    validateFilterStatesAfterUpdate(options, activeFields) {
        const columns = options.columns, fieldsToRemove = [];
        activeFields.forEach((field => {
            const column = columns.find((col => col.field === field));
            column && this.shouldEnableFilterForColumn(field, column) || fieldsToRemove.push(field);
        })), fieldsToRemove.forEach((field => {
            this.filterStateManager.dispatch({
                type: types_1.FilterActionType.REMOVE_FILTER,
                payload: {
                    field: field
                }
            });
        }));
    }
    updateFilterIcons(columns = []) {
        const filterIcon = this.pluginOptions.filterIcon, filteringIcon = this.pluginOptions.filteringIcon, isIconEqual = (a, b) => a === b || a && b && "object" == typeof a && "object" == typeof b && a.name === b.name;
        columns.forEach((column => {
            var _a;
            const shouldShow = this.shouldEnableFilterForColumn(column.field, column), isFiltering = !!(null === (_a = this.filterStateManager.getFilterState(column.field)) || void 0 === _a ? void 0 : _a.enable);
            let icons = (icons => icons ? Array.isArray(icons) ? icons : [ icons ] : [])(column.headerIcon);
            var list;
            shouldShow ? isFiltering ? icons.some((icon => isIconEqual(icon, filteringIcon))) || (icons = icons.filter((icon => !isIconEqual(icon, filterIcon))), 
            icons.push(filteringIcon)) : icons.some((icon => isIconEqual(icon, filterIcon))) || (icons = icons.filter((icon => !isIconEqual(icon, filteringIcon))), 
            icons.push(filterIcon)) : icons = icons.filter((icon => !isIconEqual(icon, filterIcon))), 
            column.headerIcon = 0 === (list = icons).length ? void 0 : 1 === list.length ? list[0] : list;
        }));
    }
    shouldEnableFilterForColumn(field, column) {
        if (!column.title) return !1;
        const columnWithFilter = column;
        return void 0 !== columnWithFilter.filter ? !!columnWithFilter.filter : this.pluginOptions.enableFilter ? this.pluginOptions.enableFilter(field, column) : void 0 === this.pluginOptions.defaultEnabled || this.pluginOptions.defaultEnabled;
    }
    getFilterState() {
        if (!this.filterStateManager) return null;
        const state = this.filterStateManager.getAllFilterStates(), serializedState = {};
        return state.filters.forEach(((config, field) => {
            serializedState[field] = {
                enable: config.enable,
                field: config.field,
                type: config.type,
                values: config.values,
                operator: config.operator,
                condition: config.condition
            };
        })), {
            filters: serializedState
        };
    }
    setFilterState(filterState) {
        this.filterStateManager && (this.filterStateManager.dispatch({
            type: types_1.FilterActionType.CLEAR_ALL_FILTERS,
            payload: {}
        }), filterState && filterState.filters && Object.entries(filterState.filters).forEach((([, config]) => {
            config.enable && this.filterStateManager.dispatch({
                type: types_1.FilterActionType.ADD_FILTER,
                payload: {
                    field: config.field,
                    type: config.type,
                    values: config.values,
                    operator: config.operator,
                    condition: config.condition,
                    enable: !0
                }
            });
        })));
    }
    release() {
        this.columns.forEach((column => {
            column.headerIcon = void 0;
        })), this.table = null, this.filterEngine = null, this.filterStateManager = null, 
        this.filterToolbar = null;
    }
}

exports.FilterPlugin = FilterPlugin;
//# sourceMappingURL=filter.js.map