/**
 * Elementor frontend handler for the Advanced Table widget.
 *
 * Adds optional client-side column sorting (numeric-aware, with ARIA state and a
 * visible arrow) and live row search/filtering. One controller per instance with
 * editor-safe teardown so re-renders inside the Elementor editor stay clean.
 *
 * @package captain-widgets-kit
 * @since   1.4.0
 */

(function ($) {
    'use strict';

    /**
     * Per-instance handler — called by Elementor for every widget instance.
     *
     * @param {jQuery} $scope - The widget wrapper element.
     */
    var CaptwikiTableHandler = function ($scope) {

        var root = $scope[0].querySelector('.captwiki-table');
        if (!root) return;

        if (root._cwkTeardown) {
            root._cwkTeardown();
        }

        var table = root.querySelector('.captwiki-table__table');
        var tbody = root.querySelector('.captwiki-table__tbody');
        if (!table || !tbody) return;

        var headers = Array.prototype.slice.call(root.querySelectorAll('.captwiki-table__th--sortable'));
        var search = root.querySelector('.captwiki-table__search');
        var emptyMsg = root.querySelector('.captwiki-table__empty');

        var handlers = [];

        /**
         * Add an event listener and remember it for later teardown.
         *
         * @param {Element} el   - Target element.
         * @param {string}  type - Event name.
         * @param {Function} fn  - Listener.
         */
        function on(el, type, fn) {
            if (!el) return;
            el.addEventListener(type, fn);
            handlers.push(function () { el.removeEventListener(type, fn); });
        }

        /**
         * Read a row's value for a given column index, numeric when possible.
         *
         * @param {Element} row   - Table row.
         * @param {number}  index - Column index.
         * @return {{num: (number|null), text: string}} Comparable value.
         */
        function cellValue(row, index) {
            var cell = row.children[index];
            var text = cell ? (cell.textContent || '').trim() : '';
            var num = parseFloat(text.replace(/[^0-9.\-]/g, ''));
            return {
                num: (text !== '' && !isNaN(num)) ? num : null,
                text: text.toLowerCase()
            };
        }

        /**
         * Sort the visible rows by a column.
         *
         * @param {number} index - Column index.
         * @param {string} dir   - 'asc' or 'desc'.
         */
        function sortBy(index, dir) {
            var rows = Array.prototype.slice.call(tbody.querySelectorAll('.captwiki-table__row'));
            var factor = dir === 'desc' ? -1 : 1;

            rows.sort(function (a, b) {
                var va = cellValue(a, index);
                var vb = cellValue(b, index);

                if (va.num !== null && vb.num !== null) {
                    return (va.num - vb.num) * factor;
                }
                if (va.text < vb.text) return -1 * factor;
                if (va.text > vb.text) return 1 * factor;
                return 0;
            });

            rows.forEach(function (row) { tbody.appendChild(row); });
        }

        /**
         * Handle a click / keyboard activation on a sortable header.
         *
         * @param {Element} header - The header cell.
         */
        function toggleSort(header) {
            var index = parseInt(header.getAttribute('data-sort-index'), 10);
            if (isNaN(index)) return;

            var currently = header.getAttribute('aria-sort');
            var dir = currently === 'ascending' ? 'desc' : 'asc';

            headers.forEach(function (h) {
                h.setAttribute('aria-sort', 'none');
                h.classList.remove('is-sorted-asc', 'is-sorted-desc');
            });

            header.setAttribute('aria-sort', dir === 'asc' ? 'ascending' : 'descending');
            header.classList.add(dir === 'asc' ? 'is-sorted-asc' : 'is-sorted-desc');

            sortBy(index, dir);
        }

        headers.forEach(function (header) {
            on(header, 'click', function () { toggleSort(header); });
            on(header, 'keydown', function (e) {
                if (e.key === 'Enter' || e.key === ' ' || e.key === 'Spacebar') {
                    e.preventDefault();
                    toggleSort(header);
                }
            });
        });

        /**
         * Filter rows against the current search term.
         */
        function applySearch() {
            var term = (search.value || '').trim().toLowerCase();
            var rows = Array.prototype.slice.call(tbody.querySelectorAll('.captwiki-table__row'));
            var visible = 0;

            rows.forEach(function (row) {
                var match = term === '' || (row.textContent || '').toLowerCase().indexOf(term) !== -1;
                row.hidden = !match;
                if (match) visible++;
            });

            if (emptyMsg) {
                emptyMsg.hidden = visible !== 0;
            }
        }

        if (search) {
            on(search, 'input', applySearch);
        }

        root._cwkTeardown = function () {
            handlers.forEach(function (off) { off(); });
            handlers = [];
            root._cwkTeardown = null;
        };
    };

    /* ── Register with Elementor frontend ───────────────────── */
    $(window).on('elementor/frontend/init', function () {
        elementorFrontend.hooks.addAction(
            'frontend/element_ready/captwiki-table.default',
            CaptwikiTableHandler
        );
    });

})(jQuery);
