/**
 * DevExtreme (cjs/__internal/grids/grid_core/header_filter/m_header_filter_core.js)
 * Version: 23.1.12
 * Build date: Fri Aug 09 2024
 *
 * Copyright (c) 2012 - 2024 Developer Express Inc. ALL RIGHTS RESERVED
 * Read about DevExtreme licensing here: https://js.devexpress.com/Licensing/
 */
"use strict";
Object.defineProperty(exports, "__esModule", {
    value: true
});
exports.headerFilterMixin = exports.allowHeaderFiltering = exports.HeaderFilterView = void 0;
exports.updateHeaderFilterItemSelectionState = updateHeaderFilterItemSelectionState;
require("../../../../ui/list/modules/search");
require("../../../../ui/list/modules/selection");
var _renderer = _interopRequireDefault(require("../../../../core/renderer"));
var _extend = require("../../../../core/utils/extend");
var _iterator = require("../../../../core/utils/iterator");
var _type = require("../../../../core/utils/type");
var _message = _interopRequireDefault(require("../../../../localization/message"));
var _list_light = _interopRequireDefault(require("../../../../ui/list_light"));
var _ui = _interopRequireDefault(require("../../../../ui/popup/ui.popup"));
var _tree_view = _interopRequireDefault(require("../../../../ui/tree_view"));
var _m_modules = _interopRequireDefault(require("../../../grids/grid_core/m_modules"));
var _m_utils = _interopRequireDefault(require("../m_utils"));

function _interopRequireDefault(obj) {
    return obj && obj.__esModule ? obj : {
        default: obj
    }
}

function _inheritsLoose(subClass, superClass) {
    subClass.prototype = Object.create(superClass.prototype);
    subClass.prototype.constructor = subClass;
    _setPrototypeOf(subClass, superClass)
}

function _setPrototypeOf(o, p) {
    _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function(o, p) {
        o.__proto__ = p;
        return o
    };
    return _setPrototypeOf(o, p)
}
var HEADER_FILTER_CLASS = "dx-header-filter";
var HEADER_FILTER_MENU_CLASS = "dx-header-filter-menu";
var DEFAULT_SEARCH_EXPRESSION = "text";

function resetChildrenItemSelection(items) {
    items = items || [];
    for (var i = 0; i < items.length; i++) {
        items[i].selected = false;
        resetChildrenItemSelection(items[i].items)
    }
}

function getSelectAllCheckBox(listComponent) {
    var selector = "dxTreeView" === listComponent.NAME ? ".dx-treeview-select-all-item" : ".dx-list-select-all-checkbox";
    return listComponent.$element().find(selector).dxCheckBox("instance")
}

function updateListSelectAllState(e, filterValues) {
    if (e.component.option("searchValue")) {
        return
    }
    var selectAllCheckBox = getSelectAllCheckBox(e.component);
    if (selectAllCheckBox && filterValues && filterValues.length) {
        selectAllCheckBox.option("value", void 0)
    }
}

function updateHeaderFilterItemSelectionState(item, filterValuesMatch, isExcludeFilter) {
    if (filterValuesMatch ^ isExcludeFilter) {
        item.selected = true;
        if (isExcludeFilter && item.items) {
            for (var j = 0; j < item.items.length; j++) {
                if (!item.items[j].selected) {
                    item.selected = void 0;
                    break
                }
            }
        }
    } else if (isExcludeFilter || item.selected) {
        item.selected = false;
        resetChildrenItemSelection(item.items)
    }
}
var HeaderFilterView = function(_Modules$View) {
    _inheritsLoose(HeaderFilterView, _Modules$View);

    function HeaderFilterView() {
        return _Modules$View.apply(this, arguments) || this
    }
    var _proto = HeaderFilterView.prototype;
    _proto.getPopupContainer = function() {
        return this._popupContainer
    };
    _proto.getListComponent = function() {
        return this._listComponent
    };
    _proto.applyHeaderFilter = function(options) {
        var list = this.getListComponent();
        var searchValue = list.option("searchValue");
        var selectAllCheckBox = getSelectAllCheckBox(list);
        var isAllSelected = !searchValue && !options.isFilterBuilder && (null === selectAllCheckBox || void 0 === selectAllCheckBox ? void 0 : selectAllCheckBox.option("value"));
        var filterValues = [];
        if (!isAllSelected) {
            if ("tree" === options.type) {
                if (options.filterType) {
                    options.filterType = "include"
                }! function fillSelectedItemKeys(filterValues, items, isExclude) {
                    (0, _iterator.each)(items, (function(_, item) {
                        if (void 0 !== item.selected && !!item.selected ^ isExclude) {
                            var node = list._getNode(item);
                            var hasChildren = list._hasChildren(node);
                            var hasChildrenWithSelection = hasChildren && item.items && item.items.some((function(item) {
                                return item.selected
                            }));
                            if (!searchValue || !hasChildrenWithSelection) {
                                filterValues.push(item.value);
                                return
                            }
                        }
                        if (item.items && item.items.length) {
                            fillSelectedItemKeys(filterValues, item.items, isExclude)
                        }
                    }))
                }(filterValues, list.option("items"), false);
                options.filterValues = filterValues
            }
        } else {
            if ("tree" === options.type) {
                options.filterType = "exclude"
            }
            if (Array.isArray(options.filterValues)) {
                options.filterValues = []
            }
        }
        if (options.filterValues && !options.filterValues.length) {
            options.filterValues = null
        }
        options.apply();
        this.hideHeaderFilterMenu()
    };
    _proto.showHeaderFilterMenu = function($columnElement, options) {
        if (options) {
            this._initializePopupContainer(options);
            var popupContainer = this.getPopupContainer();
            this.hideHeaderFilterMenu();
            this.updatePopup($columnElement, options);
            popupContainer.show()
        }
    };
    _proto.hideHeaderFilterMenu = function() {
        var headerFilterMenu = this.getPopupContainer();
        headerFilterMenu && headerFilterMenu.hide()
    };
    _proto.updatePopup = function($element, options) {
        var showColumnLines = this.option("showColumnLines");
        var alignment = "right" === options.alignment ^ !showColumnLines ? "left" : "right";
        this._popupContainer.setAria({
            role: "dialog",
            label: _message.default.format("dxDataGrid-headerFilterLabel")
        });
        if (this._popupContainer) {
            this._cleanPopupContent();
            this._popupContainer.option("position", {
                my: "".concat(alignment, " top"),
                at: "".concat(alignment, " bottom"),
                of: $element,
                collision: "fit fit"
            })
        }
    };
    _proto._getSearchExpr = function(options, headerFilterOptions) {
        var lookup = options.lookup;
        var useDefaultSearchExpr = options.useDefaultSearchExpr;
        var headerFilterDataSource = headerFilterOptions.dataSource;
        var filterSearchExpr = headerFilterOptions.search.searchExpr;
        if (filterSearchExpr) {
            return filterSearchExpr
        }
        if (useDefaultSearchExpr || (0, _type.isDefined)(headerFilterDataSource) && !(0, _type.isFunction)(headerFilterDataSource)) {
            return DEFAULT_SEARCH_EXPRESSION
        }
        if (lookup) {
            return lookup.displayExpr || "this"
        }
        if (options.dataSource) {
            var group = options.dataSource.group;
            if (Array.isArray(group) && group.length > 0) {
                return group[0].selector
            }
            if ((0, _type.isFunction)(group) && !options.remoteFiltering) {
                return group
            }
        }
        return options.dataField || options.selector
    };
    _proto._cleanPopupContent = function() {
        this._popupContainer && this._popupContainer.$content().empty()
    };
    _proto._initializePopupContainer = function(options) {
        var that = this;
        var $element = that.element();
        var headerFilterOptions = this._normalizeHeaderFilterOptions(options);
        var height = headerFilterOptions.height,
            width = headerFilterOptions.width;
        var dxPopupOptions = {
            width: width,
            height: height,
            visible: false,
            shading: false,
            showTitle: false,
            showCloseButton: false,
            hideOnParentScroll: false,
            dragEnabled: false,
            hideOnOutsideClick: true,
            wrapperAttr: {
                class: HEADER_FILTER_MENU_CLASS
            },
            focusStateEnabled: false,
            toolbarItems: [{
                toolbar: "bottom",
                location: "after",
                widget: "dxButton",
                options: {
                    text: headerFilterOptions.texts.ok,
                    onClick: function() {
                        that.applyHeaderFilter(options)
                    }
                }
            }, {
                toolbar: "bottom",
                location: "after",
                widget: "dxButton",
                options: {
                    text: headerFilterOptions.texts.cancel,
                    onClick: function() {
                        that.hideHeaderFilterMenu()
                    }
                }
            }],
            resizeEnabled: true,
            onShowing: function(e) {
                e.component.$content().parent().addClass("dx-dropdowneditor-overlay");
                that._initializeListContainer(options, headerFilterOptions);
                options.onShowing && options.onShowing(e)
            },
            onShown: function() {
                that.getListComponent().focus()
            },
            onHidden: options.onHidden,
            onInitialized: function(e) {
                var component = e.component;
                component.option("animation", component._getDefaultOptions().animation)
            }
        };
        if (!(0, _type.isDefined)(that._popupContainer)) {
            that._popupContainer = that._createComponent($element, _ui.default, dxPopupOptions)
        } else {
            that._popupContainer.option(dxPopupOptions)
        }
    };
    _proto._initializeListContainer = function(options, headerFilterOptions) {
        var that = this;
        var $content = that._popupContainer.$content();
        var needShowSelectAllCheckbox = !options.isFilterBuilder && headerFilterOptions.allowSelectAll;
        var widgetOptions = {
            searchEnabled: headerFilterOptions.search.enabled,
            searchTimeout: headerFilterOptions.search.timeout,
            searchEditorOptions: headerFilterOptions.search.editorOptions,
            searchMode: headerFilterOptions.search.mode || "",
            dataSource: options.dataSource,
            onContentReady: function() {
                that.renderCompleted.fire()
            },
            itemTemplate: function(data, _, element) {
                var $element = (0, _renderer.default)(element);
                if (options.encodeHtml) {
                    return $element.text(data.text)
                }
                return $element.html(data.text)
            }
        };

        function onOptionChanged(e) {
            if ("searchValue" === e.fullName && needShowSelectAllCheckbox && false !== that.option("headerFilter.hideSelectAllOnSearch")) {
                if ("tree" === options.type) {
                    e.component.option("showCheckBoxesMode", e.value ? "normal" : "selectAll")
                } else {
                    e.component.option("selectionMode", e.value ? "multiple" : "all")
                }
            }
        }
        if ("tree" === options.type) {
            that._listComponent = that._createComponent((0, _renderer.default)("<div>").appendTo($content), _tree_view.default, (0, _extend.extend)(widgetOptions, {
                showCheckBoxesMode: needShowSelectAllCheckbox ? "selectAll" : "normal",
                onOptionChanged: onOptionChanged,
                keyExpr: "id"
            }))
        } else {
            that._listComponent = that._createComponent((0, _renderer.default)("<div>").appendTo($content), _list_light.default, (0, _extend.extend)(widgetOptions, {
                searchExpr: that._getSearchExpr(options, headerFilterOptions),
                pageLoadMode: "scrollBottom",
                showSelectionControls: true,
                selectionMode: needShowSelectAllCheckbox ? "all" : "multiple",
                onOptionChanged: onOptionChanged,
                onSelectionChanged: function(e) {
                    var items = e.component.option("items");
                    var selectedItems = e.component.option("selectedItems");
                    if (!e.component._selectedItemsUpdating && !e.component.option("searchValue") && !options.isFilterBuilder) {
                        var filterValues = options.filterValues || [];
                        var isExclude = "exclude" === options.filterType;
                        if (0 === selectedItems.length && items.length && (filterValues.length <= 1 || isExclude && filterValues.length === items.length - 1)) {
                            options.filterType = "include";
                            options.filterValues = []
                        } else if (selectedItems.length === items.length) {
                            options.filterType = "exclude";
                            options.filterValues = []
                        }
                    }(0, _iterator.each)(items, (function(index, item) {
                        var selected = _m_utils.default.getIndexByKey(item, selectedItems, null) >= 0;
                        var oldSelected = !!item.selected;
                        if (oldSelected !== selected) {
                            item.selected = selected;
                            options.filterValues = options.filterValues || [];
                            var filterValueIndex = _m_utils.default.getIndexByKey(item.value, options.filterValues, null);
                            if (filterValueIndex >= 0) {
                                options.filterValues.splice(filterValueIndex, 1)
                            }
                            var isExcludeFilterType = "exclude" === options.filterType;
                            if (selected ^ isExcludeFilterType) {
                                options.filterValues.push(item.value)
                            }
                        }
                    }));
                    updateListSelectAllState(e, options.filterValues)
                },
                onContentReady: function(e) {
                    var component = e.component;
                    var items = component.option("items");
                    var selectedItems = [];
                    (0, _iterator.each)(items, (function() {
                        if (this.selected) {
                            selectedItems.push(this)
                        }
                    }));
                    component._selectedItemsUpdating = true;
                    component.option("selectedItems", selectedItems);
                    component._selectedItemsUpdating = false;
                    updateListSelectAllState(e, options.filterValues)
                }
            }))
        }
    };
    _proto._normalizeHeaderFilterOptions = function(options) {
        var generalHeaderFilter = this.option("headerFilter") || {};
        var specificHeaderFilter = options.headerFilter || {};
        var generalDeprecated = {
            search: {
                enabled: generalHeaderFilter.allowSearch,
                timeout: generalHeaderFilter.searchTimeout
            }
        };
        var specificDeprecated = {
            search: {
                enabled: specificHeaderFilter.allowSearch,
                mode: specificHeaderFilter.searchMode,
                timeout: specificHeaderFilter.searchTimeout
            }
        };
        return (0, _extend.extend)(true, {}, generalHeaderFilter, generalDeprecated, specificHeaderFilter, specificDeprecated)
    };
    _proto._renderCore = function() {
        this.element().addClass(HEADER_FILTER_MENU_CLASS)
    };
    return HeaderFilterView
}(_m_modules.default.View);
exports.HeaderFilterView = HeaderFilterView;
var allowHeaderFiltering = function(column) {
    return (0, _type.isDefined)(column.allowHeaderFiltering) ? column.allowHeaderFiltering : column.allowFiltering
};
exports.allowHeaderFiltering = allowHeaderFiltering;
var headerFilterMixin = function(Base) {
    return function(_Base) {
        _inheritsLoose(HeaderFilterMixin, _Base);

        function HeaderFilterMixin() {
            return _Base.apply(this, arguments) || this
        }
        var _proto2 = HeaderFilterMixin.prototype;
        _proto2.optionChanged = function(args) {
            if ("headerFilter" === args.name) {
                var requireReady = "columnHeadersView" === this.name;
                this._invalidate(requireReady, requireReady);
                args.handled = true
            } else {
                _Base.prototype.optionChanged.call(this, args)
            }
        };
        _proto2._applyColumnState = function(options) {
            var $headerFilterIndicator;
            var rootElement = options.rootElement;
            var column = options.column;
            if ("headerFilter" === options.name) {
                rootElement.find(".".concat(HEADER_FILTER_CLASS)).remove();
                if (allowHeaderFiltering(column)) {
                    $headerFilterIndicator = _Base.prototype._applyColumnState.call(this, options).toggleClass("dx-header-filter-empty", this._isHeaderFilterEmpty(column));
                    if (!this.option("useLegacyKeyboardNavigation")) {
                        $headerFilterIndicator.attr("tabindex", this.option("tabindex") || 0)
                    }
                    var indicatorLabel = _message.default.format("dxDataGrid-headerFilterIndicatorLabel", column.caption);
                    $headerFilterIndicator.attr("aria-label", indicatorLabel);
                    $headerFilterIndicator.attr("aria-haspopup", "dialog");
                    $headerFilterIndicator.attr("role", "button")
                }
                return $headerFilterIndicator
            }
            return _Base.prototype._applyColumnState.call(this, options)
        };
        _proto2._isHeaderFilterEmpty = function(column) {
            return !column.filterValues || !column.filterValues.length
        };
        _proto2._getIndicatorClassName = function(name) {
            if ("headerFilter" === name) {
                return HEADER_FILTER_CLASS
            }
            return _Base.prototype._getIndicatorClassName.call(this, name)
        };
        _proto2._renderIndicator = function(options) {
            var $container = options.container;
            var $indicator = options.indicator;
            if ("headerFilter" === options.name) {
                var rtlEnabled = this.option("rtlEnabled");
                if ($container.children().length && (!rtlEnabled && "right" === options.columnAlignment || rtlEnabled && "left" === options.columnAlignment)) {
                    $container.prepend($indicator);
                    return
                }
            }
            _Base.prototype._renderIndicator.call(this, options)
        };
        return HeaderFilterMixin
    }(Base)
};
exports.headerFilterMixin = headerFilterMixin;
