(function (window, document) {
    'use strict';

    var couponsUrlSyncTimer = null;

    function readGridCfg() {
        return typeof window.zertiCouponsGrid === 'object' && window.zertiCouponsGrid !== null
            ? window.zertiCouponsGrid
            : {};
    }

    function gridI18n() {
        var cfg = readGridCfg();
        return (cfg && cfg.i18n) || {};
    }

    function zertiPersianToLatinDigits(str) {
        return window.zertiToLatinDigits(str);
    }

    function zertiLatinToPersianDigits(str) {
        return window.zertiLocalizeDigits(str);
    }

    function readUrlParams(cfg) {
        var out = { search: '' };
        try {
            var sp = new URLSearchParams(window.location.search);
            var ps = cfg.paramSearch || 'zerti_coupons_search';
            out.search = sp.get(ps) ? String(sp.get(ps)) : '';
        } catch (e1) {
            return out;
        }
        return out;
    }

    function replaceCouponsGridUrlParams(cfg, searchInput) {
        if (couponsUrlSyncTimer) {
            window.clearTimeout(couponsUrlSyncTimer);
        }
        couponsUrlSyncTimer = window.setTimeout(function () {
            couponsUrlSyncTimer = null;
            try {
                var u = new URL(window.location.href);
                var ps = cfg.paramSearch || 'zerti_coupons_search';
                var q = searchInput && searchInput.value ? zertiPersianToLatinDigits(searchInput.value).trim() : '';
                if (q) {
                    u.searchParams.set(ps, q);
                } else {
                    u.searchParams.delete(ps);
                }
                var next = u.pathname + u.search + window.location.hash;
                var cur = window.location.pathname + window.location.search + window.location.hash;
                if (next !== cur) {
                    window.history.replaceState(null, '', next);
                }
            } catch (e2) {}
        }, 280);
    }

    function textComparator(a, b) {
        return String(a || '').localeCompare(String(b || ''), 'fa');
    }

    function numericComparator(key) {
        return function (valueA, valueB, nodeA, nodeB) {
            var a = nodeA && nodeA.data ? Number(nodeA.data[key]) : NaN;
            var b = nodeB && nodeB.data ? Number(nodeB.data[key]) : NaN;
            if (Number.isNaN(a)) {
                a = 0;
            }
            if (Number.isNaN(b)) {
                b = 0;
            }
            return a - b;
        };
    }

    function createFilterOptionCache() {
        return window.zertiAgGridCreateFilterOptionCache({
            type: [],
        });
    }

    function seedTypeFilterOptions(filterOptionCache, cfg) {
        var labels = [];
        if (Array.isArray(cfg.couponTypeLabels)) {
            cfg.couponTypeLabels.forEach(function (label) {
                var value = label !== undefined && label !== null ? String(label) : '';
                if (value !== '' && labels.indexOf(value) === -1) {
                    labels.push(value);
                }
            });
        }
        labels.sort(textComparator);
        filterOptionCache.type = labels;
    }

    function appendCouponFilterOptions(filterOptionCache, rows) {
        var existing = {};
        filterOptionCache.type.forEach(function (value) {
            existing[value] = true;
        });
        rows.forEach(function (row) {
            var value = row && row.type !== undefined && row.type !== null ? String(row.type) : '';
            if (value === '' || value === '—' || existing[value]) {
                return;
            }
            existing[value] = true;
            filterOptionCache.type.push(value);
        });
        filterOptionCache.type.sort(textComparator);
        if (typeof filterOptionCache.notifyFilterOptionsChanged === 'function') {
            filterOptionCache.notifyFilterOptionsChanged();
        }
    }

    function dropdownFilter(filterOptionCache, field) {
        return window.zertiAgGridInlineDropdownFilterColumn({
            cache: filterOptionCache,
            field: field,
            selectClass: 'zerti-coupons-grid-filter-select',
            filterAllLabel: gridI18n().filterAll || '',
        });
    }

    function buildColumnDefs(filterOptionCache) {
        var i18n = gridI18n();
        return [
            {
                colId: 'c0',
                field: 'code',
                headerName: i18n.colCode || 'Code',
                comparator: textComparator,
                minWidth: 140,
            },
            Object.assign(
                {
                    colId: 'c1',
                    field: 'type',
                    headerName: i18n.colType || 'Type',
                    comparator: textComparator,
                    minWidth: 130,
                    filterValueGetter: function (params) {
                        return params.data ? params.data.type : '';
                    },
                },
                dropdownFilter(filterOptionCache, 'type')
            ),
            {
                colId: 'c2',
                field: 'amount',
                headerName: i18n.colAmount || 'Amount',
                comparator: numericComparator('amount_sort'),
                minWidth: 110,
            },
            {
                colId: 'c3',
                field: 'description',
                headerName: i18n.colDescription || 'Description',
                comparator: textComparator,
                minWidth: 160,
                flex: 1.2,
            },
            {
                colId: 'c4',
                field: 'products',
                headerName: i18n.colProducts || 'Product IDs',
                comparator: textComparator,
                minWidth: 120,
            },
            {
                colId: 'c5',
                field: 'usage',
                headerName: i18n.colUsage || 'Usage / Limit',
                comparator: textComparator,
                minWidth: 120,
            },
            {
                colId: 'c6',
                field: 'expiry_date',
                headerName: i18n.colExpiry || 'Expiry date',
                comparator: numericComparator('expiry_sort'),
                minWidth: 130,
            },
        ];
    }

    function installSearchToolbar(wrap, cfg, initialSearch) {
        if (!wrap) {
            return null;
        }

        var toolbar = wrap.querySelector('.zerti-coupons-grid-toolbar');
        if (!toolbar) {
            return null;
        }

        var searchSlot = toolbar.querySelector('.zerti-coupons-grid-toolbar-search');
        if (!searchSlot) {
            return null;
        }
        searchSlot.innerHTML = '';

        var label = document.createElement('label');
        label.className = 'zerti-coupons-grid-search-label form-label mb-0';
        label.setAttribute('for', 'zertiCouponsGridSearch');

        var icon = document.createElement('i');
        icon.className = 'fa-solid fa-magnifying-glass zerti-coupons-grid-search-icon';
        icon.setAttribute('aria-hidden', 'true');

        var input = document.createElement('input');
        input.type = 'search';
        input.id = 'zertiCouponsGridSearch';
        input.className = 'form-control form-control-sm zerti-coupons-grid-search-input';
        input.setAttribute('autocomplete', 'off');
        input.setAttribute('dir', window.zertiAdminTextDirection ? window.zertiAdminTextDirection() : 'rtl');
        input.setAttribute('aria-label', cfg.searchAriaLabel || '');
        input.placeholder = cfg.searchPlaceholder || '';
        input.value = initialSearch ? zertiLatinToPersianDigits(initialSearch) : '';

        label.appendChild(icon);
        label.appendChild(input);
        searchSlot.appendChild(label);

        return input;
    }

    function createCouponsLoadingState(gridEl) {
        var activeRequests = 0;
        var el = document.createElement('div');
        el.className = 'zerti-coupons-grid-loading';
        el.setAttribute('role', 'status');
        el.setAttribute('aria-live', 'polite');
        el.hidden = true;
        el.textContent = gridI18n().loadingData || '';
        gridEl.appendChild(el);

        return {
            show: function () {
                activeRequests += 1;
                el.hidden = false;
            },
            hide: function () {
                activeRequests = Math.max(0, activeRequests - 1);
                if (activeRequests === 0) {
                    el.hidden = true;
                }
            },
            destroy: function () {
                activeRequests = 0;
                if (el.parentNode) {
                    el.parentNode.removeChild(el);
                }
            },
        };
    }

    function refreshCouponsInfiniteCache(api, resetPage, dataSourceFactory) {
        if (resetPage && api && api.paginationGoToFirstPage) {
            api.paginationGoToFirstPage();
        }
        if (dataSourceFactory && api) {
            if (api.setGridOption) {
                api.setGridOption('datasource', dataSourceFactory());
                return;
            }
            if (api.setDatasource) {
                api.setDatasource(dataSourceFactory());
                return;
            }
        }
        if (api && api.purgeInfiniteCache) {
            api.purgeInfiniteCache();
        } else if (api && api.refreshInfiniteCache) {
            api.refreshInfiniteCache();
        }
    }

    function fetchCouponsPage(cfg, page, pageSize, search, filterModel) {
        var body = new window.FormData();
        body.append('action', cfg.action || 'zerti_wc_coupons_grid');
        body.append('nonce', cfg.nonce || '');
        body.append('page', String(page));
        body.append('page_size', String(pageSize));
        body.append('search', search || '');
        body.append('filter_model', JSON.stringify(filterModel || {}));

        return window
            .fetch(cfg.ajaxUrl || '', {
                method: 'POST',
                credentials: 'same-origin',
                body: body,
            })
            .then(function (res) {
                if (!res.ok) {
                    throw new Error('http ' + res.status);
                }
                return res.json();
            })
            .then(function (data) {
                if (!data || !data.success || !data.data) {
                    throw new Error('bad response');
                }
                return data.data;
            });
    }

    function createCouponsDataSource(cfg, searchInput, filterOptionCache, loadingState, api, gridEl) {
        return {
            getRows: function (params) {
                var pageSize = Number(cfg.pageSize || 50);
                var page = Math.floor((params.startRow || 0) / pageSize) + 1;
                var filterModel =
                    typeof window.zertiAgGridEffectiveFilterModel === 'function'
                        ? window.zertiAgGridEffectiveFilterModel(api, gridEl)
                        : api && api.getFilterModel
                          ? api.getFilterModel()
                          : params.filterModel || {};
                if (loadingState && loadingState.show) {
                    loadingState.show();
                }
                fetchCouponsPage(cfg, page, pageSize, currentSearch(searchInput), filterModel)
                    .then(function (payload) {
                        var rows = Array.isArray(payload.rows) ? payload.rows : [];
                        var total = Number(payload.total || 0);
                        gridEl.__zertiCouponsTotal = total;
                        appendCouponFilterOptions(filterOptionCache, rows);
                        if (typeof window.zertiAgGridRefreshInlineFilterHeaders === 'function') {
                            window.zertiAgGridRefreshInlineFilterHeaders(api, filterOptionCache);
                        }
                        params.successCallback(rows, total);
                        if (loadingState && loadingState.hide) {
                            loadingState.hide();
                        }
                    })
                    .catch(function () {
                        params.failCallback();
                        if (loadingState && loadingState.hide) {
                            loadingState.hide();
                        }
                    });
            },
        };
    }

    function currentSearch(searchInput) {
        return searchInput && searchInput.value ? zertiPersianToLatinDigits(searchInput.value).trim() : '';
    }

    function zertiInitCouponsTable(root, options) {
        options = options || {};
        if (!root || !window.agGrid || typeof window.agGrid.createGrid !== 'function') {
            return null;
        }
        var gridEl = root.querySelector('#zertiCouponsGrid');
        if (!gridEl) {
            return null;
        }

        if (typeof gridEl.__zertiAgGridCleanup === 'function') {
            gridEl.__zertiAgGridCleanup();
            gridEl.__zertiAgGridCleanup = null;
        }
        if (gridEl.__zertiAgGridApi && typeof gridEl.__zertiAgGridApi.destroy === 'function') {
            gridEl.__zertiAgGridApi.destroy();
            gridEl.__zertiAgGridApi = null;
        }

        var wrap = gridEl.closest('.zerti-coupons-wrap');
        var cfg = readGridCfg();
        var urlP = readUrlParams(cfg);
        var pageSize = Number(cfg.pageSize || 50);
        var searchInput = installSearchToolbar(wrap, cfg, urlP.search);
        var searchTimer = null;
        var filterOptionCache = createFilterOptionCache();
        seedTypeFilterOptions(filterOptionCache, cfg);
        if (typeof filterOptionCache.notifyFilterOptionsChanged === 'function') {
            filterOptionCache.notifyFilterOptionsChanged();
        }
        gridEl.__zertiFilterOptionCache = filterOptionCache;

        var gridOptions = {
            theme: 'legacy',
            rowModelType: 'infinite',
            components: typeof window.zertiAgGridComponents === 'function' ? window.zertiAgGridComponents() : {},
            columnDefs: buildColumnDefs(filterOptionCache),
            defaultColDef: {
                flex: 1,
                sortable: true,
                resizable: true,
                filter: false,
                floatingFilter: false,
                cellClass: 'zerti-coupons-grid-cell',
            },
            enableRtl: window.zertiIsAdminRtl ? window.zertiIsAdminRtl() : true,
            animateRows: true,
            pagination: true,
            paginationPageSize: pageSize,
            paginationPageSizeSelector: false,
            paginationPanels: ['pageSummary', 'rowSummary'],
            cacheBlockSize: pageSize,
            maxBlocksInCache: 4,
            paginationNumberFormatter: function (params) {
                return zertiLatinToPersianDigits(params.value);
            },
            localeText: window.zertiAgGridLocaleText(gridI18n(), 'noRowsToShow'),
            getRowId: function (params) {
                return String(params.data.id);
            },
            suppressRowClickSelection: true,
            onRowClicked: function (event) {
                if (!event || !event.data || typeof options.onRowClick !== 'function') {
                    return;
                }
                var target = event.event && event.event.target;
                if (
                    target &&
                    target.closest &&
                    target.closest(
                        'a, button, select, input, textarea, label, .ag-header, .ag-filter, .ag-paging-panel, .zerti-coupons-grid-toolbar'
                    )
                ) {
                    return;
                }
                options.onRowClick(event.data);
            },
            onFilterChanged: function (event) {
                if (typeof window.zertiAgGridSyncInlineFilterHeaders === 'function') {
                    window.zertiAgGridSyncInlineFilterHeaders(event.api, gridEl.__zertiFilterOptionCache);
                }
                gridEl.__zertiCouponsTotal = undefined;
                refreshCouponsInfiniteCache(event.api, true, gridEl.__zertiAgGridDataSourceFactory);
            },
        };

        gridEl.__zertiCouponsTotal = undefined;
        var api = window.agGrid.createGrid(gridEl, gridOptions);
        var loadingState = createCouponsLoadingState(gridEl);
        var dataSourceFactoryFn = function () {
            return createCouponsDataSource(cfg, searchInput, filterOptionCache, loadingState, api, gridEl);
        };
        gridEl.__zertiAgGridDataSourceFactory = dataSourceFactoryFn;
        gridEl.__zertiAgGridApi = api;

        if (api.setGridOption) {
            api.setGridOption('datasource', dataSourceFactoryFn());
        } else if (api.setDatasource) {
            api.setDatasource(dataSourceFactoryFn());
        }

        function refreshGrid(resetPage) {
            replaceCouponsGridUrlParams(cfg, searchInput);
            refreshCouponsInfiniteCache(api, !!resetPage, dataSourceFactoryFn);
        }

        if (searchInput) {
            searchInput.addEventListener('input', function () {
                if (searchTimer) {
                    window.clearTimeout(searchTimer);
                }
                searchTimer = window.setTimeout(function () {
                    gridEl.__zertiCouponsTotal = undefined;
                    refreshGrid(true);
                }, 320);
            });
        }

        gridEl.__zertiAgGridCleanup = function () {
            if (searchTimer) {
                window.clearTimeout(searchTimer);
                searchTimer = null;
            }
            if (loadingState && loadingState.destroy) {
                loadingState.destroy();
            }
        };

        gridEl.classList.add('zerti-coupons-grid--row-nav');

        return {
            refresh: function () {
                refreshGrid(true);
            },
            destroy: function () {
                if (typeof gridEl.__zertiAgGridCleanup === 'function') {
                    gridEl.__zertiAgGridCleanup();
                    gridEl.__zertiAgGridCleanup = null;
                }
                if (gridEl.__zertiAgGridApi && typeof gridEl.__zertiAgGridApi.destroy === 'function') {
                    gridEl.__zertiAgGridApi.destroy();
                    gridEl.__zertiAgGridApi = null;
                }
            },
        };
    }

    window.zertiInitCouponsTable = zertiInitCouponsTable;
})(window, document);
