(function (window) {
    'use strict';

    /**
     * Active ZERTI admin text direction (rtl|ltr).
     */
    window.zertiAdminTextDirection = function () {
        var root = document.getElementById('zertiAdmin');
        if (root) {
            var dir = root.getAttribute('dir');
            if (dir === 'ltr' || dir === 'rtl') {
                return dir;
            }
        }
        var cfg = window.zertiComponents;
        if (cfg && (cfg.textDirection === 'ltr' || cfg.textDirection === 'rtl')) {
            return cfg.textDirection;
        }
        return 'rtl';
    };

    window.zertiIsAdminRtl = function () {
        return window.zertiAdminTextDirection() === 'rtl';
    };

    /**
     * Font Awesome chevron class for inventory tree expand/collapse toggles.
     *
     * @param {boolean} isExpanded
     * @return {string}
     */
    window.zertiTreeChevronClass = function (isExpanded) {
        if (isExpanded) {
            return 'fa-chevron-down';
        }
        return window.zertiIsAdminRtl() ? 'fa-chevron-left' : 'fa-chevron-right';
    };

    /**
     * Build AG Grid localeText from a ZERTI grid cfg.i18n object.
     *
     * @param {Record<string, string>|undefined} i18n
     * @param {string} [noRowsKey]
     * @return {Record<string, string>}
     */
    window.zertiAgGridLocaleText = function (i18n, noRowsKey) {
        i18n = i18n || {};
        var out = {
            page: '',
            more: i18n.more || '',
            to: i18n.to || '',
            of: i18n.of || '',
            next: i18n.next || '',
            last: i18n.last || '',
            first: i18n.first || '',
            previous: i18n.previous || '',
            loadingOoo: i18n.loadingOoo || '',
            noRowsToShow: i18n[noRowsKey || 'noRowsToShow'] || '',
        };
        return out;
    };

    function zertiGridFilterDisplayValue(value) {
        if (window.zertiLocalizeDigits) {
            return window.zertiLocalizeDigits(value);
        }
        return value == null ? '' : String(value);
    }

    /**
     * AG Grid custom filter — dropdown model { value } for server-side grids.
     */
    function ZertiAgGridDropdownFilter() {}

    ZertiAgGridDropdownFilter.prototype.init = function (params) {
        this.params = params;
        this.filterChangedCallback = params.filterChangedCallback;
        this.value = '';
        this.valueField = params.valueField || (params.colDef && params.colDef.field) || '';
        this.eGui = document.createElement('div');
        this.eGui.className = 'zerti-grid-hidden-filter-host';
        this.eGui.hidden = true;
    };

    ZertiAgGridDropdownFilter.prototype.getGui = function () {
        return this.eGui;
    };

    ZertiAgGridDropdownFilter.prototype.isFilterActive = function () {
        return this.value !== '';
    };

    ZertiAgGridDropdownFilter.prototype.doesFilterPass = function () {
        return true;
    };

    ZertiAgGridDropdownFilter.prototype.getModel = function () {
        return this.isFilterActive() ? { value: this.value } : null;
    };

    ZertiAgGridDropdownFilter.prototype.setModel = function (model) {
        this.value = model && model.value !== undefined ? String(model.value) : '';
    };

    /**
     * Apply a dropdown filter value and notify AG Grid (infinite/server-side lists).
     *
     * @param {object|null} api
     * @param {string} colId
     * @param {string} value
     */
    window.zertiAgGridApplyColumnFilterValue = function (api, colId, value) {
        if (!api || !colId) {
            return;
        }
        var model = value ? { value: String(value) } : null;
        var gridEl = typeof api.getGridElement === 'function' ? api.getGridElement() : null;
        var next = {};
        if (gridEl && gridEl.__zertiAgGridFilterModel && typeof gridEl.__zertiAgGridFilterModel === 'object') {
            next = Object.assign({}, gridEl.__zertiAgGridFilterModel);
        } else if (typeof api.getFilterModel === 'function') {
            next = Object.assign({}, api.getFilterModel() || {});
        }
        if (model) {
            next[colId] = model;
        } else {
            delete next[colId];
        }
        var hasFilters = Object.keys(next).length > 0;
        if (gridEl) {
            gridEl.__zertiAgGridFilterModel = hasFilters ? next : null;
        }
        if (typeof api.setFilterModel === 'function') {
            api.setFilterModel(hasFilters ? next : null);
        }
        if (typeof api.onFilterChanged === 'function') {
            api.onFilterChanged();
        }
    };

    /**
     * Filter model for server requests — prefers cached model from inline header filters.
     *
     * @param {object|null} api
     * @param {HTMLElement|null} gridEl
     * @return {object}
     */
    window.zertiAgGridEffectiveFilterModel = function (api, gridEl) {
        if (gridEl && gridEl.__zertiAgGridFilterModel && typeof gridEl.__zertiAgGridFilterModel === 'object') {
            return gridEl.__zertiAgGridFilterModel;
        }
        if (api && typeof api.getFilterModel === 'function') {
            var model = api.getFilterModel();
            if (model && typeof model === 'object') {
                return model;
            }
        }
        return {};
    };

    window.zertiAgGridDropdownFilter = ZertiAgGridDropdownFilter;

    /**
     * Column header: title + filter icon; dropdown shown on icon click.
     */
    function ZertiInlineFilterHeader() {
        this.params = null;
        this.eGui = null;
        this.select = null;
        this.labelWrap = null;
        this.filterBtn = null;
        this.filterPanel = null;
        this.rowWrap = null;
        this._boundDocumentPointer = null;
    }

    ZertiInlineFilterHeader.prototype.readHeaderParams = function (params) {
        params = params || this.params || {};
        var p = params.headerComponentParams;
        if (!p && params.column && typeof params.column.getColDef === 'function') {
            var colDef = params.column.getColDef() || {};
            p = colDef.headerComponentParams;
        }
        return p || {};
    };

    ZertiInlineFilterHeader.prototype.readOptions = function (params) {
        var p = this.readHeaderParams(params);
        if (typeof p.getOptions === 'function') {
            var fromGetter = p.getOptions();
            return Array.isArray(fromGetter) ? fromGetter.slice() : [];
        }
        if (Array.isArray(p.staticOptions) && p.staticOptions.length) {
            return p.staticOptions.slice();
        }
        var ref = p.filterOptionsRef;
        var field = p.filterOptionsField;
        if (ref && field && Array.isArray(ref[field])) {
            return ref[field].slice();
        }
        return [];
    };

    ZertiInlineFilterHeader.prototype.rebuildOptions = function (params) {
        if (!this.select) {
            return;
        }
        var p = this.readHeaderParams(params);
        var filterAllLabel = p.filterAllLabel != null ? String(p.filterAllLabel) : '';
        var current = this.select.value;
        while (this.select.firstChild) {
            this.select.removeChild(this.select.firstChild);
        }
        var empty = document.createElement('option');
        empty.value = '';
        empty.textContent = filterAllLabel;
        this.select.appendChild(empty);
        this.readOptions(params).forEach(function (entry) {
            var option = document.createElement('option');
            if (entry && typeof entry === 'object' && entry.value !== undefined) {
                option.value = String(entry.value);
                option.textContent = zertiGridFilterDisplayValue(entry.label != null ? entry.label : entry.value);
            } else {
                option.value = String(entry);
                option.textContent = zertiGridFilterDisplayValue(entry);
            }
            this.select.appendChild(option);
        }, this);
        if (current) {
            var hasCurrent = false;
            Array.prototype.forEach.call(this.select.options, function (opt) {
                if (opt.value === current) {
                    hasCurrent = true;
                }
            });
            if (hasCurrent) {
                this.select.value = current;
            }
        }
        this.updateFilterButtonState();
    };

    ZertiInlineFilterHeader.prototype.updateFilterButtonState = function () {
        if (!this.filterBtn || !this.select || !this.eGui) {
            return;
        }
        var active = this.select.value !== '';
        this.filterBtn.classList.toggle('is-active', active);
        this.eGui.classList.toggle('has-active-filter', active);
    };

    ZertiInlineFilterHeader.prototype.closeFilterPanel = function () {
        if (!this.eGui) {
            return;
        }
        this.eGui.classList.remove('is-filter-open');
        if (this.filterBtn) {
            this.filterBtn.setAttribute('aria-expanded', 'false');
        }
    };

    ZertiInlineFilterHeader.prototype.closeOtherFilterPanels = function () {
        var gridEl =
            this.params && this.params.api && typeof this.params.api.getGridElement === 'function'
                ? this.params.api.getGridElement()
                : null;
        var scope = gridEl || document;
        scope.querySelectorAll('.zerti-grid-inline-filter-header.is-filter-open').forEach(
            function (node) {
                if (node !== this.eGui) {
                    node.classList.remove('is-filter-open');
                    var btn = node.querySelector('.zerti-grid-inline-filter-header__toggle');
                    if (btn) {
                        btn.setAttribute('aria-expanded', 'false');
                    }
                }
            }.bind(this)
        );
    };

    ZertiInlineFilterHeader.prototype.openFilterPanel = function () {
        if (!this.eGui) {
            return;
        }
        this.closeOtherFilterPanels();
        this.eGui.classList.add('is-filter-open');
        if (this.filterBtn) {
            this.filterBtn.setAttribute('aria-expanded', 'true');
        }
    };

    ZertiInlineFilterHeader.prototype.toggleFilterPanel = function (event) {
        if (event) {
            event.stopPropagation();
            event.preventDefault();
        }
        if (!this.eGui) {
            return;
        }
        if (this.eGui.classList.contains('is-filter-open')) {
            this.closeFilterPanel();
            return;
        }
        this.openFilterPanel();
    };

    ZertiInlineFilterHeader.prototype.onDocumentPointer = function (event) {
        if (!this.eGui || !this.eGui.classList.contains('is-filter-open')) {
            return;
        }
        var target = event.target;
        if (target && this.eGui.contains(target)) {
            return;
        }
        this.closeFilterPanel();
    };

    ZertiInlineFilterHeader.prototype.syncFromFilterModel = function () {
        if (!this.select || !this.params) {
            return;
        }
        var p = this.readHeaderParams(this.params);
        if (typeof p.getFilterValue === 'function') {
            this.select.value = String(p.getFilterValue() || '');
            this.updateFilterButtonState();
            return;
        }
        if (!this.params.api || !this.params.column || typeof this.params.column.getColId !== 'function') {
            return;
        }
        var colId = this.params.column.getColId();
        var modelMap = this.params.api.getFilterModel ? this.params.api.getFilterModel() : {};
        var model = modelMap && modelMap[colId];
        this.select.value = model && model.value !== undefined && model.value !== null ? String(model.value) : '';
        this.updateFilterButtonState();
    };

    ZertiInlineFilterHeader.prototype.applyFilterValue = function (value) {
        var params = this.params;
        if (!params) {
            return;
        }
        var p = this.readHeaderParams(params);
        if (typeof p.onFilterChange === 'function') {
            p.onFilterChange(value);
            return;
        }
        if (!params.api || !params.column || typeof params.column.getColId !== 'function') {
            return;
        }
        if (typeof window.zertiAgGridApplyColumnFilterValue === 'function') {
            window.zertiAgGridApplyColumnFilterValue(params.api, params.column.getColId(), value);
        }
    };

    ZertiInlineFilterHeader.prototype.onSelectChange = function () {
        if (!this.select) {
            return;
        }
        this.updateFilterButtonState();
        this.applyFilterValue(this.select.value);
    };

    ZertiInlineFilterHeader.prototype.stopHeaderPointer = function (event) {
        event.stopPropagation();
    };

    ZertiInlineFilterHeader.prototype.init = function (params) {
        this.params = params;
        var p = this.readHeaderParams(params);
        this.eGui = document.createElement('div');
        this.eGui.className = 'zerti-grid-inline-filter-header';

        this.rowWrap = document.createElement('div');
        this.rowWrap.className = 'zerti-grid-inline-filter-header__row';

        this.labelWrap = document.createElement('div');
        this.labelWrap.className = 'zerti-grid-inline-filter-header__label-wrap';

        var label = document.createElement('span');
        label.className = 'zerti-grid-inline-filter-header__label ag-header-cell-text';
        label.textContent = params.displayName || (params.column && params.column.getColDef && params.column.getColDef().headerName) || '';

        if (params.enableSorting) {
            this.labelWrap.classList.add('ag-header-cell-sortable');
            this.labelWrap.addEventListener('click', function (event) {
                params.progressSort(event.shiftKey);
            });
        }
        this.labelWrap.appendChild(label);

        this.filterBtn = document.createElement('button');
        this.filterBtn.type = 'button';
        this.filterBtn.className = 'zerti-grid-inline-filter-header__toggle';
        this.filterBtn.setAttribute('aria-expanded', 'false');
        this.filterBtn.setAttribute(
            'aria-label',
            (label.textContent ? label.textContent + ' — ' : '') + (p.filterToggleLabel || 'Filter')
        );
        this.filterBtn.innerHTML =
            '<svg class="zerti-grid-inline-filter-header__toggle-icon" viewBox="0 0 16 16" width="14" height="14" aria-hidden="true" focusable="false">' +
            '<path fill="currentColor" d="M1.5 2.5A.5.5 0 0 1 2 2h12a.5.5 0 0 1 .4.8L10 8.5V13.5a.5.5 0 0 1-.276.447l-2 1A.5.5 0 0 1 7 15V8.5L1.6 2.8A.5.5 0 0 1 1.5 2.5z"/>' +
            '</svg>';
        this.filterBtn.addEventListener('click', this.toggleFilterPanel.bind(this));
        this.filterBtn.addEventListener('mousedown', this.stopHeaderPointer);

        this.filterPanel = document.createElement('div');
        this.filterPanel.className = 'zerti-grid-inline-filter-header__panel';
        this.filterPanel.addEventListener('click', this.stopHeaderPointer);
        this.filterPanel.addEventListener('mousedown', this.stopHeaderPointer);

        this.select = document.createElement('select');
        this.select.className =
            'form-select form-select-sm zerti-admin-select ' + (p.selectClass || 'zerti-grid-filter-select');
        this.select.setAttribute('aria-label', label.textContent || '');
        this.select.addEventListener('change', this.onSelectChange.bind(this));
        this.select.addEventListener('click', this.stopHeaderPointer);
        this.select.addEventListener('mousedown', this.stopHeaderPointer);

        this._boundOptionsRefresh = this.onFilterOptionsChanged.bind(this);
        var optionsRef = p.filterOptionsRef;
        if (optionsRef && typeof optionsRef.onFilterOptionsChanged === 'function') {
            optionsRef.onFilterOptionsChanged(this._boundOptionsRefresh);
        }

        this.rebuildOptions(params);
        this.syncFromFilterModel();

        this.filterPanel.appendChild(this.select);
        this.rowWrap.appendChild(this.labelWrap);
        this.rowWrap.appendChild(this.filterBtn);
        this.eGui.appendChild(this.rowWrap);
        this.eGui.appendChild(this.filterPanel);

        this._boundDocumentPointer = this.onDocumentPointer.bind(this);
        document.addEventListener('mousedown', this._boundDocumentPointer);
    };

    ZertiInlineFilterHeader.prototype.onFilterOptionsChanged = function () {
        if (!this.params) {
            return;
        }
        this.rebuildOptions(this.params);
        this.syncFromFilterModel();
    };

    ZertiInlineFilterHeader.prototype.getGui = function () {
        return this.eGui;
    };

    ZertiInlineFilterHeader.prototype.refresh = function (params) {
        this.params = params;
        this.rebuildOptions(params);
        this.syncFromFilterModel();
        return true;
    };

    ZertiInlineFilterHeader.prototype.destroy = function () {
        if (this._boundOptionsRefresh && this.params) {
            var p = this.readHeaderParams(this.params);
            var optionsRef = p.filterOptionsRef;
            if (optionsRef && typeof optionsRef.offFilterOptionsChanged === 'function') {
                optionsRef.offFilterOptionsChanged(this._boundOptionsRefresh);
            }
        }
        if (this._boundDocumentPointer) {
            document.removeEventListener('mousedown', this._boundDocumentPointer);
        }
        this._boundDocumentPointer = null;
        this._boundOptionsRefresh = null;
        this.params = null;
        this.eGui = null;
        this.select = null;
        this.labelWrap = null;
        this.filterBtn = null;
        this.filterPanel = null;
        this.rowWrap = null;
    };

    window.zertiAgGridComponents = function () {
        return {
            zertiInlineFilterHeader: ZertiInlineFilterHeader,
        };
    };

    /**
     * Column def fragment: filter icon in header; dropdown opens on click.
     *
     * @param {{ cache?: object, field?: string, selectClass?: string, filterAllLabel?: string, staticOptions?: Array, onFilterChange?: Function, getFilterValue?: Function }} opts
     */
    window.zertiAgGridCreateFilterOptionCache = function (fields) {
        var cache = fields && typeof fields === 'object' ? fields : {};
        cache.__filterOptionListeners = [];
        cache.onFilterOptionsChanged = function (listener) {
            if (typeof listener === 'function') {
                cache.__filterOptionListeners.push(listener);
            }
        };
        cache.offFilterOptionsChanged = function (listener) {
            cache.__filterOptionListeners = (cache.__filterOptionListeners || []).filter(function (fn) {
                return fn !== listener;
            });
        };
        cache.notifyFilterOptionsChanged = function () {
            (cache.__filterOptionListeners || []).forEach(function (listener) {
                listener();
            });
        };
        return cache;
    };

    window.zertiAgGridInlineDropdownFilterColumn = function (opts) {
        opts = opts || {};
        var field = opts.field || '';
        var cache = opts.cache || null;
        var staticOptions = opts.staticOptions || null;
        return {
            filter: window.zertiAgGridDropdownFilter,
            floatingFilter: false,
            suppressHeaderFilterButton: true,
            headerComponent: 'zertiInlineFilterHeader',
            filterParams: {
                valueField: field,
            },
            headerComponentParams: {
                filterOptionsRef: cache,
                filterOptionsField: field,
                selectClass: opts.selectClass || 'zerti-grid-filter-select',
                filterAllLabel: opts.filterAllLabel != null ? opts.filterAllLabel : '',
                staticOptions: staticOptions,
                onFilterChange: opts.onFilterChange || null,
                getFilterValue: opts.getFilterValue || null,
                getOptions: function () {
                    if (typeof opts.getOptions === 'function') {
                        var custom = opts.getOptions();
                        return Array.isArray(custom) ? custom.slice() : [];
                    }
                    if (Array.isArray(staticOptions) && staticOptions.length) {
                        return staticOptions.slice();
                    }
                    if (cache && field && Array.isArray(cache[field])) {
                        return cache[field].slice();
                    }
                    return [];
                },
            },
        };
    };

    window.zertiAgGridRefreshInlineFilterHeaders = function (api, cache) {
        if (cache && typeof cache.notifyFilterOptionsChanged === 'function') {
            cache.notifyFilterOptionsChanged();
            return;
        }
        if (api && api.refreshHeader) {
            api.refreshHeader();
        }
    };

    window.zertiAgGridSyncInlineFilterHeaders = function (api, cache) {
        window.zertiAgGridRefreshInlineFilterHeaders(api, cache);
    };
})(window);
