/**
 * RSL Accordion System - Accessible Column and Classic Accordion Components
 *
 * Provides two accordion implementations with full keyboard navigation, ARIA support,
 * and focus management. Supports both single-open and multi-open modes with
 * intelligent focus detection for keyboard vs mouse interactions.
 *
 * @fileoverview Accessible accordion components with keyboard navigation
 * @version 2.0.0
 * @license MIT
 *
 * Key Features:
 * - Two accordion types: column-based and classic
 * - Full ARIA accessibility support
 * - Keyboard navigation (Arrow keys, Home, End, Enter, Space)
 * - Auto-open on keyboard focus (Tab/Shift+Tab)
 * - Single-open or multi-open modes
 * - Dynamic ARIA labels with content preview
 * - Fancy accordion styling support
 * - Focus tracking (keyboard vs mouse/pointer)
 * - JSON Layout API compatible
 *
 * Accordion Types:
 * - Column-based: .accordion with .accordion-item > .accordion-title + .accordion-content
 * - Classic: .classic-accordion with same structure (includes fancy variant)
 *
 * Usage:
 * // Column-based accordion:
 * <div class="accordion" data-single-open="true">
 *   <div class="accordion-item">
 *     <button class="accordion-title">Section 1</button>
 *     <div class="accordion-content">Content here...</div>
 *   </div>
 * </div>
 *
 * // Classic accordion:
 * <div class="classic-accordion" data-single-open="false">
 *   <div class="accordion-item">
 *     <button class="accordion-title">Section 1</button>
 *     <div class="accordion-content">Content here...</div>
 *   </div>
 * </div>
 *
 * Data Attributes:
 * - data-single-open="true" - Only one panel can be open at a time (accordion behavior)
 * - data-single-open="false" - Multiple panels can be open (default)
 * - data-filterbus-key="keyName" - Filter key to subscribe to (e.g., "category")
 * - data-{key}="value" - On accordion items, defines the value for filtering
 *
 * Keyboard Navigation:
 * - Enter/Space - Toggle accordion panel
 * - Tab - Auto-opens panel when focused via keyboard
 * - Arrow Down/Right - Focus next accordion title
 * - Arrow Up/Left - Focus previous accordion title
 * - Home - Focus first accordion title
 * - End - Focus last accordion title
 *
 * Public API:
 * - RSL.Accordion.init() - Initialize all accordions on the page
 * - RSL.Accordion.create(container) - Initialize a specific accordion container
 *
 * FilterBus Integration (Visibility Mode):
 * Accordion items can be shown/hidden based on FilterBus filter state.
 * Add data-filterbus-key to the accordion container specifying which filter
 * key to listen to. Add data-{key} attributes to accordion items.
 *
 * Example:
 * <div class="accordion" data-filterbus-key="category">
 *   <div class="accordion-item" data-category="general">...</div>
 *   <div class="accordion-item" data-category="billing">...</div>
 * </div>
 *
 * When FilterBus.publish('category', 'billing') is called, only billing items show.
 */

(function() {
    'use strict';

    window.RSL = window.RSL || {};

    /**
     * Track whether last interaction was from keyboard vs mouse/pointer
     * Used to determine if accordion should auto-open on focus
     * @type {boolean}
     */
    let rslLastInteractionWasKeyboard = false;

    /**
     * Track keyboard interactions globally
     * Sets flag to true when any key is pressed
     */
    window.addEventListener(
        'keydown',
        () => {
            rslLastInteractionWasKeyboard = true;
        },
        { capture: true }
    );

    /**
     * Track pointer interactions globally
     * Sets flag to false when mouse, pointer, or touch is used
     */
    ['mousedown', 'pointerdown', 'touchstart'].forEach((type) => {
        window.addEventListener(
            type,
            () => {
                rslLastInteractionWasKeyboard = false;
            },
            { capture: true }
        );
    });

    window.RSL.Accordion = {
        /**
         * Track initialized accordion containers to prevent double-initialization
         */
        instances: new Set(),

        /**
         * Initialize all accordion containers on the page
         * Automatically called on DOMContentLoaded and by JSON Layout API
         */
        init: function() {
            const containers = document.querySelectorAll('.accordion, .classic-accordion');
            containers.forEach(function(container) {
                if (!RSL.Accordion.instances.has(container)) {
                    RSL.Accordion.create(container);
                }
            });
        },

        /**
         * Create and initialize a specific accordion container
         * @param {HTMLElement} container - The accordion container element
         */
        create: function(container) {
            if (RSL.Accordion.instances.has(container)) {
                return; // Already initialized
            }

            const isClassic = container.classList.contains('classic-accordion');
            const titles = container.querySelectorAll('.accordion-title');

            titles.forEach(function(element) {
                // Click event
                element.addEventListener('click', function() {
                    if (isClassic) {
                        RSL.Accordion._toggleClassic(element);
                    } else {
                        RSL.Accordion._toggle(element);
                    }
                });

                // Keyboard events (Enter/Space)
                element.addEventListener('keydown', function(event) {
                    if (event.key === 'Enter' || event.key === ' ') {
                        event.preventDefault();
                        if (isClassic) {
                            RSL.Accordion._toggleClassic(element);
                        } else {
                            RSL.Accordion._toggle(element);
                        }
                    }
                });

                // Auto-open when focused from keyboard (Tab/Shift+Tab)
                element.addEventListener('focus', function() {
                    if (!rslLastInteractionWasKeyboard) return;

                    const content = element.nextElementSibling;
                    if (content && !content.classList.contains('open')) {
                        if (isClassic) {
                            RSL.Accordion._toggleClassic(element);
                        } else {
                            RSL.Accordion._toggle(element);
                        }
                    }
                });
            });

            // Initialize arrow key navigation
            RSL.Accordion._initArrowNavigation(container);

            // Mark as initialized
            RSL.Accordion.instances.add(container);
        },

        /**
         * Toggle accordion panel open/closed state for column-based accordion
         * @private
         * @param {HTMLElement} element - The accordion title button element
         */
        _toggle: function(element) {
            const accordionContainer = element.closest('.accordion');
            if (!accordionContainer) return;

            const items = Array.from(accordionContainer.querySelectorAll('.accordion-item'));
            const totalAccordions = items.length;
            const thisAccordionIndex = items.indexOf(element.parentElement) + 1;

            const content = element.nextElementSibling;
            if (!content) return;

            const text = content.textContent.trim();
            const isOpen = content.classList.contains('open');

            const singleOpen = accordionContainer.dataset.singleOpen === 'true';

            // If this group is single-open and we're opening this one, close all siblings first
            if (singleOpen && !isOpen) {
                items.forEach((item) => {
                    const header = item.querySelector('.accordion-title');
                    const panel = header && header.nextElementSibling;
                    if (!header || !panel || panel === content) return;

                    panel.classList.remove('open');
                    header.setAttribute('aria-expanded', 'false');
                    header.setAttribute('aria-label', '');
                });
            }

            // Toggle 'open' class for this panel
            content.classList.toggle('open');

            // Set ARIA-expanded attribute to reflect new state
            element.setAttribute('aria-expanded', String(!isOpen));

            // Set ARIA-label dynamically based on the content text
            const ariaLabel = isOpen
                ? ''
                : `${element.textContent}, ${thisAccordionIndex} of ${totalAccordions}, press tab to skip, ${element.textContent} Content, ${text}`;
            element.setAttribute('aria-label', ariaLabel);

            // Trigger layout recalculation for any grids inside the newly opened panel
            if (!isOpen && content.classList.contains('open')) {
                const gridLayouts = content.querySelectorAll('.slot-layout, .nested-slot-layout');
                gridLayouts.forEach(function(layout) {
                    window.dispatchEvent(new Event('resize'));
                });
            }
        },

        /**
         * Toggle accordion panel open/closed state for classic accordion
         * @private
         * @param {HTMLElement} element - The accordion title button element
         */
        _toggleClassic: function(element) {
            const accordionContainer = element.closest('.classic-accordion');
            if (!accordionContainer) return;

            const items = Array.from(accordionContainer.querySelectorAll('.accordion-item'));
            const totalAccordions = items.length;
            const thisAccordionIndex = items.indexOf(element.parentElement) + 1;

            const content = element.nextElementSibling;
            if (!content) return;

            const text = content.textContent.trim();
            const isOpen = content.classList.contains('open');

            const singleOpen = accordionContainer.dataset.singleOpen === 'true';

            // If this group is single-open and we're opening this one, close all siblings first
            if (singleOpen && !isOpen) {
                items.forEach((item) => {
                    const header = item.querySelector('.accordion-title');
                    const panel = header && header.nextElementSibling;
                    if (!header || !panel || panel === content) return;

                    panel.classList.remove('open');
                    header.setAttribute('aria-expanded', 'false');
                    header.setAttribute('aria-label', '');
                });
            }

            // Toggle 'open' class
            content.classList.toggle('open');

            // Set ARIA-expanded attribute to reflect new state
            element.setAttribute('aria-expanded', String(!isOpen));

            // Set ARIA-label dynamically based on the content text
            const ariaLabel = isOpen
                ? ''
                : `${element.textContent}, ${thisAccordionIndex} of ${totalAccordions}, press tab to skip, ${element.textContent} Content, ${text}`;
            element.setAttribute('aria-label', ariaLabel);

            // Trigger layout recalculation for any grids inside the newly opened panel
            if (!isOpen && content.classList.contains('open')) {
                const gridLayouts = content.querySelectorAll('.slot-layout, .nested-slot-layout');
                gridLayouts.forEach(function(layout) {
                    window.dispatchEvent(new Event('resize'));
                });
            }
        },

        /**
         * Initialize arrow key navigation for an accordion container
         * @private
         * @param {HTMLElement} container - The accordion container
         */
        _initArrowNavigation: function(container) {
            const triggers = Array.from(container.querySelectorAll('.accordion-title'));
            if (triggers.length < 2) return;

            triggers.forEach((btn, index) => {
                btn.addEventListener('keydown', (e) => {
                    const key = e.key;
                    let target = null;

                    if (key === 'ArrowDown' || key === 'ArrowRight') {
                        e.preventDefault();
                        target = triggers[index + 1] || triggers[0];
                    } else if (key === 'ArrowUp' || key === 'ArrowLeft') {
                        e.preventDefault();
                        target = triggers[index - 1] || triggers[triggers.length - 1];
                    } else if (key === 'Home') {
                        e.preventDefault();
                        target = triggers[0];
                    } else if (key === 'End') {
                        e.preventDefault();
                        target = triggers[triggers.length - 1];
                    }

                    if (target) {
                        target.focus(); // focus triggers the existing focus-to-open logic
                    }
                });
            });
        },

        /**
         * Initialize FilterBus subscription for an accordion container
         * Enables visibility filtering of accordion items based on filter state
         * @private
         * @param {HTMLElement} container - The accordion container with data-filterbus-key
         */
        _initFilterBus: function(container) {
            const filterKey = container.getAttribute('data-filterbus-key');
            if (!filterKey) return;

            // Check if FilterBus is available
            if (!window.RSL || !window.RSL.FilterBus) {
                console.warn('RSL.Accordion: FilterBus not available for key:', filterKey);
                return;
            }

            const items = container.querySelectorAll('.accordion-item');
            if (items.length === 0) return;

            // Generate unique subscriber ID
            const subscriberId = 'accordion-' + filterKey + '-' + Date.now();

            // Subscribe to FilterBus for this specific key
            window.RSL.FilterBus.subscribe(subscriberId, function(state) {
                const filterValue = state[filterKey];

                items.forEach(function(item) {
                    const itemValue = item.getAttribute('data-' + filterKey);

                    // Show all if no filter value or empty
                    if (!filterValue || filterValue === '' || filterValue === 'All') {
                        item.classList.remove('filterbus-hidden');
                        return;
                    }

                    // Check if item matches the filter
                    const shouldShow = (itemValue === filterValue);

                    if (shouldShow) {
                        item.classList.remove('filterbus-hidden');
                    } else {
                        item.classList.add('filterbus-hidden');
                        // Close the accordion panel if it's hidden
                        const content = item.querySelector('.accordion-content');
                        if (content && content.classList.contains('open')) {
                            content.classList.remove('open');
                            const title = item.querySelector('.accordion-title');
                            if (title) {
                                title.setAttribute('aria-expanded', 'false');
                            }
                        }
                    }
                });
            }, { keys: [filterKey] });
        }
    };

    // Auto-initialize on page load
    document.addEventListener('DOMContentLoaded', function() {
        RSL.Accordion.init();

        // Initialize FilterBus subscriptions for accordions with data-filterbus-key
        const filterBusAccordions = document.querySelectorAll('.accordion[data-filterbus-key], .classic-accordion[data-filterbus-key]');
        filterBusAccordions.forEach(function(container) {
            RSL.Accordion._initFilterBus(container);
        });
    });

})();
