/**
 * DevExtreme (esm/__internal/grids/grid_core/filter/m_filter_panel.js)
 * Version: 22.2.7 (build 23185-0311)
 * Build date: Tue Jul 04 2023
 *
 * Copyright (c) 2012 - 2023 Developer Express Inc. ALL RIGHTS RESERVED
 * Read about DevExtreme licensing here: https://js.devexpress.com/Licensing/
 */
import $ from "../../../../core/renderer";
import {
    Deferred,
    when
} from "../../../../core/utils/deferred";
import {
    captionize
} from "../../../../core/utils/inflector";
import {
    isDefined
} from "../../../../core/utils/type";
import eventsEngine from "../../../../events/core/events_engine";
import messageLocalization from "../../../../localization/message";
import CheckBox from "../../../../ui/check_box";
import {
    getCaptionByOperation,
    getCurrentLookupValueText,
    getCurrentValueText,
    getCustomOperation,
    getField,
    getGroupValue,
    isCondition,
    isGroup
} from "../../../../ui/filter_builder/utils";
import {
    registerKeyboardAction
} from "../m_accessibility";
import modules from "../m_modules";
import gridUtils from "../m_utils";
var FILTER_PANEL_CLASS = "filter-panel";
var FILTER_PANEL_TEXT_CLASS = "".concat(FILTER_PANEL_CLASS, "-text");
var FILTER_PANEL_CHECKBOX_CLASS = "".concat(FILTER_PANEL_CLASS, "-checkbox");
var FILTER_PANEL_CLEAR_FILTER_CLASS = "".concat(FILTER_PANEL_CLASS, "-clear-filter");
var FILTER_PANEL_LEFT_CONTAINER = "".concat(FILTER_PANEL_CLASS, "-left");
var FILTER_PANEL_TARGET = "filterPanel";
var FilterPanelView = modules.View.inherit({
    isVisible() {
        return this.option("filterPanel.visible") && this.getController("data").dataSource()
    },
    init() {
        this.getController("data").dataSourceChanged.add(() => this.render());
        this._columnsController = this.getController("columns")
    },
    _renderCore() {
        var $element = this.element();
        $element.empty();
        var isColumnsDefined = !!this._columnsController.getColumns().length;
        if (!isColumnsDefined) {
            return
        }
        $element.addClass(this.addWidgetPrefix(FILTER_PANEL_CLASS));
        var $leftContainer = $("<div>").addClass(this.addWidgetPrefix(FILTER_PANEL_LEFT_CONTAINER)).appendTo($element);
        this._renderFilterBuilderText($element, $leftContainer)
    },
    _renderFilterBuilderText($element, $leftContainer) {
        var $filterElement = this._getFilterElement();
        var $textElement = this._getTextElement();
        if (this.option("filterValue") || this._filterValueBuffer) {
            var $checkElement = this._getCheckElement();
            var $removeButtonElement = this._getRemoveButtonElement();
            $leftContainer.append($checkElement).append($filterElement).append($textElement);
            $element.append($removeButtonElement);
            return
        }
        $leftContainer.append($filterElement).append($textElement)
    },
    _getCheckElement() {
        var that = this;
        var $element = $("<div>").addClass(this.addWidgetPrefix(FILTER_PANEL_CHECKBOX_CLASS));
        that._createComponent($element, CheckBox, {
            value: that.option("filterPanel.filterEnabled"),
            onValueChanged(e) {
                that.option("filterPanel.filterEnabled", e.value)
            }
        });
        $element.attr("title", this.option("filterPanel.texts.filterEnabledHint"));
        return $element
    },
    _getFilterElement() {
        var that = this;
        var $element = $("<div>").addClass("dx-icon-filter");
        eventsEngine.on($element, "click", () => that._showFilterBuilder());
        registerKeyboardAction("filterPanel", that, $element, void 0, () => that._showFilterBuilder());
        that._addTabIndexToElement($element);
        return $element
    },
    _getTextElement() {
        var that = this;
        var $textElement = $("<div>").addClass(that.addWidgetPrefix(FILTER_PANEL_TEXT_CLASS));
        var filterText;
        var filterValue = that.option("filterValue");
        if (filterValue) {
            when(that.getFilterText(filterValue, that.getController("filterSync").getCustomFilterOperations())).done(filterText => {
                var customizeText = that.option("filterPanel.customizeText");
                if (customizeText) {
                    var customText = customizeText({
                        component: that.component,
                        filterValue: filterValue,
                        text: filterText
                    });
                    if ("string" === typeof customText) {
                        filterText = customText
                    }
                }
                $textElement.text(filterText)
            })
        } else {
            filterText = that.option("filterPanel.texts.createFilter");
            $textElement.text(filterText)
        }
        eventsEngine.on($textElement, "click", () => that._showFilterBuilder());
        registerKeyboardAction("filterPanel", that, $textElement, void 0, () => that._showFilterBuilder());
        that._addTabIndexToElement($textElement);
        return $textElement
    },
    _showFilterBuilder() {
        this.option("filterBuilderPopup.visible", true)
    },
    _getRemoveButtonElement() {
        var that = this;
        var clearFilterValue = () => that.option("filterValue", null);
        var $element = $("<div>").addClass(that.addWidgetPrefix(FILTER_PANEL_CLEAR_FILTER_CLASS)).text(that.option("filterPanel.texts.clearFilter"));
        eventsEngine.on($element, "click", clearFilterValue);
        registerKeyboardAction("filterPanel", this, $element, void 0, clearFilterValue);
        that._addTabIndexToElement($element);
        return $element
    },
    _addTabIndexToElement($element) {
        if (!this.option("useLegacyKeyboardNavigation")) {
            var tabindex = this.option("tabindex") || 0;
            $element.attr("tabindex", tabindex)
        }
    },
    optionChanged(args) {
        switch (args.name) {
            case "filterValue":
                this._invalidate();
                this.option("filterPanel.filterEnabled", true);
                args.handled = true;
                break;
            case "filterPanel":
                this._invalidate();
                args.handled = true;
                break;
            default:
                this.callBase(args)
        }
    },
    _getConditionText(fieldText, operationText, valueText) {
        var result = "[".concat(fieldText, "] ").concat(operationText);
        if (isDefined(valueText)) {
            result += valueText
        }
        return result
    },
    _getValueMaskedText: value => Array.isArray(value) ? "('".concat(value.join("', '"), "')") : " '".concat(value, "'"),
    _getValueText(field, customOperation, value) {
        var deferred = new Deferred;
        var hasCustomOperation = customOperation && customOperation.customizeText;
        if (isDefined(value) || hasCustomOperation) {
            if (!hasCustomOperation && field.lookup) {
                getCurrentLookupValueText(field, value, data => {
                    deferred.resolve(this._getValueMaskedText(data))
                })
            } else {
                var displayValue = Array.isArray(value) ? value : gridUtils.getDisplayValue(field, value, null);
                when(getCurrentValueText(field, displayValue, customOperation, FILTER_PANEL_TARGET)).done(data => {
                    deferred.resolve(this._getValueMaskedText(data))
                })
            }
        } else {
            deferred.resolve("")
        }
        return deferred.promise()
    },
    getConditionText(filterValue, options) {
        var that = this;
        var operation = filterValue[1];
        var deferred = new Deferred;
        var customOperation = getCustomOperation(options.customOperations, operation);
        var operationText;
        var field = getField(filterValue[0], options.columns);
        var fieldText = field.caption || "";
        var value = filterValue[2];
        if (customOperation) {
            operationText = customOperation.caption || captionize(customOperation.name)
        } else if (null === value) {
            operationText = getCaptionByOperation("=" === operation ? "isblank" : "isnotblank", options.filterOperationDescriptions)
        } else {
            operationText = getCaptionByOperation(operation, options.filterOperationDescriptions)
        }
        this._getValueText(field, customOperation, value).done(valueText => {
            deferred.resolve(that._getConditionText(fieldText, operationText, valueText))
        });
        return deferred
    },
    getGroupText(filterValue, options, isInnerGroup) {
        var that = this;
        var result = new Deferred;
        var textParts = [];
        var groupValue = getGroupValue(filterValue);
        filterValue.forEach(item => {
            if (isCondition(item)) {
                textParts.push(that.getConditionText(item, options))
            } else if (isGroup(item)) {
                textParts.push(that.getGroupText(item, options, true))
            }
        });
        when.apply(this, textParts).done((function() {
            var text;
            for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
                args[_key] = arguments[_key]
            }
            if (groupValue.startsWith("!")) {
                var groupText = options.groupOperationDescriptions["not".concat(groupValue.substring(1, 2).toUpperCase()).concat(groupValue.substring(2))].split(" ");
                text = "".concat(groupText[0], " ").concat(args[0])
            } else {
                text = args.join(" ".concat(options.groupOperationDescriptions[groupValue], " "))
            }
            if (isInnerGroup) {
                text = "(".concat(text, ")")
            }
            result.resolve(text)
        }));
        return result
    },
    getFilterText(filterValue, customOperations) {
        var options = {
            customOperations: customOperations,
            columns: this.getController("columns").getFilteringColumns(),
            filterOperationDescriptions: this.option("filterBuilder.filterOperationDescriptions"),
            groupOperationDescriptions: this.option("filterBuilder.groupOperationDescriptions")
        };
        return isCondition(filterValue) ? this.getConditionText(filterValue, options) : this.getGroupText(filterValue, options)
    }
});
export var filterPanelModule = {
    defaultOptions: () => ({
        filterPanel: {
            visible: false,
            filterEnabled: true,
            texts: {
                createFilter: messageLocalization.format("dxDataGrid-filterPanelCreateFilter"),
                clearFilter: messageLocalization.format("dxDataGrid-filterPanelClearFilter"),
                filterEnabledHint: messageLocalization.format("dxDataGrid-filterPanelFilterEnabledHint")
            }
        }
    }),
    views: {
        filterPanelView: FilterPanelView
    },
    extenders: {
        controllers: {
            data: {
                optionChanged(args) {
                    switch (args.name) {
                        case "filterPanel":
                            this._applyFilter();
                            args.handled = true;
                            break;
                        default:
                            this.callBase(args)
                    }
                }
            }
        }
    }
};
