/**
 * Elementor frontend handler for the Accordion widget.
 *
 * Drives panel expand / collapse with a measured height animation, keeps
 * ARIA state ( aria-expanded + hidden ) in sync, honours single / multi open
 * mode and adds arrow-key / Home / End navigation between headers.
 * Editor-safe teardown per instance.
 *
 * @package captain-widgets-kit
 * @since   1.7.0
 */

(function ($) {
    'use strict';

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

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

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

        var items = Array.prototype.slice.call(root.querySelectorAll('.captwiki-accordion__item'));
        if (items.length === 0) return;

        var allowMultiple = root.getAttribute('data-multiple') === 'yes';
        var buttons = [];
        var handlers = [];

        /**
         * Bind an event with automatic teardown registration.
         *
         * @param {Element} el   - Target element.
         * @param {string}  type - Event type.
         * @param {Function} fn  - Listener.
         */
        function on(el, type, fn) {
            el.addEventListener(type, fn);
            handlers.push(function () { el.removeEventListener(type, fn); });
        }

        /**
         * Cancel a pending end-of-animation listener so a re-toggle mid
         * animation can never apply a stale state ( e.g. hide an open panel ).
         *
         * @param {Element} panel - The panel element.
         */
        function clearPending(panel) {
            if (panel._cwkAnimDone) {
                panel.removeEventListener('transitionend', panel._cwkAnimDone);
                panel._cwkAnimDone = null;
            }
        }

        /**
         * Animate a panel to its natural height, then release to auto.
         *
         * @param {Element} panel - The panel element.
         */
        function expand(panel) {
            clearPending(panel);
            panel.removeAttribute('hidden');
            panel.style.height = '0px';
            panel.style.overflow = 'hidden';

            window.requestAnimationFrame(function () {
                panel.style.transition = 'height 0.3s ease';
                panel.style.height = panel.scrollHeight + 'px';
            });

            var done = function (e) {
                if (e.propertyName !== 'height') return;
                panel.style.transition = '';
                panel.style.height = '';
                panel.style.overflow = '';
                clearPending(panel);
            };
            panel._cwkAnimDone = done;
            panel.addEventListener('transitionend', done);
        }

        /**
         * Animate a panel closed, then hide it from assistive tech.
         *
         * @param {Element} panel - The panel element.
         */
        function collapse(panel) {
            clearPending(panel);
            panel.style.height = panel.scrollHeight + 'px';
            panel.style.overflow = 'hidden';

            window.requestAnimationFrame(function () {
                panel.style.transition = 'height 0.3s ease';
                panel.style.height = '0px';
            });

            var done = function (e) {
                if (e.propertyName !== 'height') return;
                panel.style.transition = '';
                panel.style.height = '';
                panel.style.overflow = '';
                panel.setAttribute('hidden', '');
                clearPending(panel);
            };
            panel._cwkAnimDone = done;
            panel.addEventListener('transitionend', done);
        }

        /**
         * Open or close one item, closing siblings in single-open mode.
         *
         * @param {Element} item - The accordion item element.
         */
        function toggle(item) {
            var isOpen = item.classList.contains('is-open');

            if (!isOpen && !allowMultiple) {
                items.forEach(function (other) {
                    if (other !== item && other.classList.contains('is-open')) {
                        setState(other, false);
                    }
                });
            }

            setState(item, !isOpen);
        }

        /**
         * Apply the open / closed state to an item.
         *
         * @param {Element} item - The accordion item element.
         * @param {boolean} open - Target state.
         */
        function setState(item, open) {
            var button = item.querySelector('.captwiki-accordion__button');
            var panel = item.querySelector('.captwiki-accordion__panel');
            if (!button || !panel) return;

            item.classList.toggle('is-open', open);
            button.setAttribute('aria-expanded', open ? 'true' : 'false');

            if (open) {
                expand(panel);
            } else {
                collapse(panel);
            }
        }

        /* ── Events ────────────────────────────────────────── */
        items.forEach(function (item) {
            var button = item.querySelector('.captwiki-accordion__button');
            if (!button) return;

            buttons.push(button);
            on(button, 'click', function () { toggle(item); });
        });

        on(root, 'keydown', function (e) {
            var current = buttons.indexOf(document.activeElement);
            if (current === -1) return;

            var next = null;

            if (e.key === 'ArrowDown') {
                next = (current + 1) % buttons.length;
            } else if (e.key === 'ArrowUp') {
                next = (current - 1 + buttons.length) % buttons.length;
            } else if (e.key === 'Home') {
                next = 0;
            } else if (e.key === 'End') {
                next = buttons.length - 1;
            }

            if (next !== null) {
                e.preventDefault();
                buttons[next].focus();
            }
        });

        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-accordion.default',
            CaptwikiAccordionHandler
        );
    });

})(jQuery);
