/* ============================================
   RSL Filter Component
   Version: 1.0.0
   Description: Premium global filter system with
   pub/sub architecture, multiple UI styles,
   and full accessibility support.

   Features:
   - FilterBus: Central pub/sub system for cross-component communication
   - Multiple UI styles: pills, buttons, dropdown, chips, toggle, search, radio, checkbox
   - Full WCAG 2.1 AA accessibility with keyboard navigation
   - Live announcements for screen readers
   - Optional localStorage persistence
   - Multi-select and single-select modes
   - JSON API V2 ready
   ============================================ */

(function() {
    'use strict';

    // Initialize RSL namespace
    window.RSL = window.RSL || {};

    /* ============================================
       FilterBus - Global Pub/Sub System
       The heart of the filter architecture.
       Any component can subscribe to receive
       filter updates.
       ============================================ */
    window.RSL.FilterBus = {

        /**
         * Subscribers map: id → { callback, options }
         * @private
         */
        _subscribers: new Map(),

        /**
         * Current filter state
         * @private
         */
        _state: {},

        /**
         * State history for undo
         * @private
         */
        _history: [],

        /**
         * Maximum history length
         * @private
         */
        _maxHistory: 50,

        /**
         * Whether to persist state to localStorage
         * @private
         */
        _persistKey: null,

        /**
         * Subscribe a component to filter updates
         * @param {string} id - Unique subscriber identifier
         * @param {Function} callback - Function to call with filter state
         * @param {Object} [options] - Subscription options
         * @param {Array} [options.keys] - Only listen to specific filter keys
         * @param {boolean} [options.immediate] - Call callback immediately with current state
         * @returns {Function} Unsubscribe function
         */
        subscribe: function(id, callback, options) {
            if (typeof callback !== 'function') {
                console.error('[RSL.FilterBus] Callback must be a function');
                return function() {};
            }

            options = options || {};

            this._subscribers.set(id, {
                callback: callback,
                keys: options.keys || null,
                immediate: options.immediate !== false
            });

            // Call immediately with current state if requested
            if (options.immediate !== false && Object.keys(this._state).length > 0) {
                try {
                    callback(this.getState(), { source: 'subscribe', key: null });
                } catch (e) {
                    console.error('[RSL.FilterBus] Error in subscriber callback:', e);
                }
            }

            // Return unsubscribe function
            var self = this;
            return function() {
                self.unsubscribe(id);
            };
        },

        /**
         * Unsubscribe a component from filter updates
         * @param {string} id - Subscriber identifier
         */
        unsubscribe: function(id) {
            this._subscribers.delete(id);
        },

        /**
         * Publish a filter change
         * @param {string} key - Filter key
         * @param {*} value - Filter value (null/undefined to clear)
         * @param {Object} [options] - Publish options
         * @param {string} [options.source] - Source identifier
         * @param {boolean} [options.silent] - Don't notify subscribers
         * @param {boolean} [options.persist] - Persist to localStorage
         */
        publish: function(key, value, options) {
            options = options || {};

            // Save to history for undo
            this._saveHistory();

            // Update state
            if (value === null || value === undefined || value === '' ||
                (Array.isArray(value) && value.length === 0)) {
                delete this._state[key];
            } else {
                this._state[key] = value;
            }

            // Persist if enabled
            if (this._persistKey || options.persist) {
                this._persist();
            }

            // Dispatch custom event
            this._dispatchEvent('rsl-filter-change', {
                key: key,
                value: value,
                state: this.getState(),
                source: options.source || 'unknown'
            });

            // Notify subscribers
            if (!options.silent) {
                this._notifySubscribers(key, options.source);
            }
        },

        /**
         * Apply multiple filter changes at once
         * @param {Object} updates - Object of key/value pairs
         * @param {Object} [options] - Batch options
         */
        batch: function(updates, options) {
            options = options || {};

            // Save to history
            this._saveHistory();

            // Apply all updates
            var keys = Object.keys(updates);
            for (var i = 0; i < keys.length; i++) {
                var key = keys[i];
                var value = updates[key];

                if (value === null || value === undefined || value === '' ||
                    (Array.isArray(value) && value.length === 0)) {
                    delete this._state[key];
                } else {
                    this._state[key] = value;
                }
            }

            // Persist if enabled
            if (this._persistKey || options.persist) {
                this._persist();
            }

            // Dispatch event
            this._dispatchEvent('rsl-filter-change', {
                key: null,
                value: null,
                state: this.getState(),
                source: options.source || 'batch',
                batch: true,
                keys: keys
            });

            // Notify subscribers
            if (!options.silent) {
                this._notifySubscribers(null, options.source, keys);
            }
        },

        /**
         * Clear a specific filter
         * @param {string} key - Filter key to clear
         * @param {Object} [options] - Clear options
         */
        clear: function(key, options) {
            this.publish(key, null, options);

            this._dispatchEvent('rsl-filter-clear', {
                key: key,
                state: this.getState(),
                source: (options && options.source) || 'clear'
            });
        },

        /**
         * Clear all filters
         * @param {Object} [options] - Clear options
         */
        clearAll: function(options) {
            options = options || {};

            // Save to history
            this._saveHistory();

            // Clear state
            this._state = {};

            // Persist if enabled
            if (this._persistKey) {
                this._persist();
            }

            // Dispatch event
            this._dispatchEvent('rsl-filter-clear', {
                key: null,
                state: {},
                source: options.source || 'clearAll',
                all: true
            });

            // Notify subscribers
            if (!options.silent) {
                this._notifySubscribers(null, 'clearAll');
            }
        },

        /**
         * Get current filter state (immutable copy)
         * @returns {Object} Current filter state
         */
        getState: function() {
            return JSON.parse(JSON.stringify(this._state));
        },

        /**
         * Get a specific filter value
         * @param {string} key - Filter key
         * @param {*} [defaultValue] - Default if not set
         * @returns {*} Filter value
         */
        getValue: function(key, defaultValue) {
            if (this._state.hasOwnProperty(key)) {
                return this._state[key];
            }
            return defaultValue;
        },

        /**
         * Check if any filters are active
         * @returns {boolean}
         */
        hasActiveFilters: function() {
            return Object.keys(this._state).length > 0;
        },

        /**
         * Get count of active filters
         * @returns {number}
         */
        getActiveCount: function() {
            return Object.keys(this._state).length;
        },

        /**
         * Undo last filter change
         * @returns {boolean} Whether undo was performed
         */
        undo: function() {
            if (this._history.length === 0) {
                return false;
            }

            this._state = this._history.pop();

            if (this._persistKey) {
                this._persist();
            }

            this._dispatchEvent('rsl-filter-change', {
                key: null,
                value: null,
                state: this.getState(),
                source: 'undo'
            });

            this._notifySubscribers(null, 'undo');

            return true;
        },

        /**
         * Enable localStorage persistence
         * @param {string} key - localStorage key
         */
        persist: function(key) {
            this._persistKey = key;
            this._persist();
        },

        /**
         * Restore state from localStorage
         * @param {string} key - localStorage key
         * @returns {boolean} Whether restore was successful
         */
        restore: function(key) {
            try {
                var stored = localStorage.getItem(key);
                if (stored) {
                    this._state = JSON.parse(stored);
                    this._persistKey = key;

                    this._dispatchEvent('rsl-filter-change', {
                        key: null,
                        value: null,
                        state: this.getState(),
                        source: 'restore'
                    });

                    this._notifySubscribers(null, 'restore');
                    return true;
                }
            } catch (e) {
                console.error('[RSL.FilterBus] Error restoring state:', e);
            }
            return false;
        },

        /**
         * Save state to history
         * @private
         */
        _saveHistory: function() {
            this._history.push(JSON.parse(JSON.stringify(this._state)));
            if (this._history.length > this._maxHistory) {
                this._history.shift();
            }
        },

        /**
         * Persist state to localStorage
         * @private
         */
        _persist: function() {
            if (this._persistKey) {
                try {
                    localStorage.setItem(this._persistKey, JSON.stringify(this._state));
                } catch (e) {
                    console.error('[RSL.FilterBus] Error persisting state:', e);
                }
            }
        },

        /**
         * Notify all subscribers of a change
         * @private
         */
        _notifySubscribers: function(changedKey, source, batchKeys) {
            var state = this.getState();
            var meta = {
                key: changedKey,
                source: source || 'unknown',
                batch: !!batchKeys,
                batchKeys: batchKeys || null
            };

            this._subscribers.forEach(function(subscriber, id) {
                // Check if subscriber cares about this key
                if (subscriber.keys && changedKey && !subscriber.keys.includes(changedKey)) {
                    // Check batch keys
                    if (batchKeys) {
                        var interested = false;
                        for (var i = 0; i < batchKeys.length; i++) {
                            if (subscriber.keys.includes(batchKeys[i])) {
                                interested = true;
                                break;
                            }
                        }
                        if (!interested) return;
                    } else {
                        return;
                    }
                }

                try {
                    subscriber.callback(state, meta);
                } catch (e) {
                    console.error('[RSL.FilterBus] Error in subscriber "' + id + '":', e);
                }
            });
        },

        /**
         * Dispatch a custom event
         * @private
         */
        _dispatchEvent: function(eventName, detail) {
            var event = new CustomEvent(eventName, {
                bubbles: true,
                detail: detail
            });
            document.dispatchEvent(event);
        }
    };


    /* ============================================
       Filter Component - UI Management
       Handles the visual filter controls.
       ============================================ */

    /**
     * Track initialized filter instances
     * @type {Map<HTMLElement, Object>}
     */
    var instances = new Map();

    /**
     * Data attribute to config mapping
     */
    var ATTR_MAP = {
        'data-filter-key': 'key',
        'data-filter-style': 'style',
        'data-filter-multi': 'multi',
        'data-filter-default': 'defaultValue',
        'data-filter-persist': 'persist',
        'data-filter-announce': 'announce',
        'data-filter-label': 'label',
        'data-filter-size': 'size',
        'data-filter-color': 'color',
        'data-filter-placeholder': 'placeholder',
        'data-filter-debounce': 'debounce',
        'data-filter-layout': 'layout',
        'data-filter-show-clear': 'showClear',
        'data-filter-show-count': 'showCount',
        'data-filter-show-summary': 'showSummary'
    };

    /**
     * Default configuration
     */
    var DEFAULTS = {
        key: null,
        style: 'pills',
        multi: false,
        defaultValue: null,
        persist: false,
        announce: true,
        label: null,
        size: 'md',
        color: 'primary',
        placeholder: 'Search...',
        debounce: 300,
        layout: 'horizontal',
        showClear: true,
        showCount: false,
        showSummary: false
    };

    /**
     * Parse a data attribute value
     */
    function parseValue(value, defaultValue) {
        if (value === null || value === undefined) return defaultValue;
        if (value === '' || value === 'true') return true;
        if (value === 'false') return false;

        try {
            return JSON.parse(value);
        } catch (e) {
            var num = parseFloat(value);
            return isNaN(num) ? value : num;
        }
    }

    /**
     * Get configuration from element
     */
    function getConfig(element) {
        var config = Object.assign({}, DEFAULTS);

        Object.keys(ATTR_MAP).forEach(function(attr) {
            var value = element.getAttribute(attr);
            if (value !== null) {
                config[ATTR_MAP[attr]] = parseValue(value, config[ATTR_MAP[attr]]);
            }
        });

        return config;
    }

    /**
     * Create live region for announcements
     */
    function createLiveRegion(container) {
        var region = document.createElement('div');
        region.className = 'rsl-filter-announce';
        region.setAttribute('role', 'status');
        region.setAttribute('aria-live', 'polite');
        region.setAttribute('aria-atomic', 'true');
        container.appendChild(region);
        return region;
    }

    /**
     * Announce to screen readers
     */
    function announce(instance, message) {
        if (!instance.config.announce || !instance.liveRegion) return;

        instance.liveRegion.textContent = '';
        // Force reflow
        void instance.liveRegion.offsetHeight;
        instance.liveRegion.textContent = message;
    }

    /**
     * Get display label for a value
     */
    function getValueLabel(instance, value) {
        var option = instance.options.find(function(opt) {
            return opt.value === value || opt.value === String(value);
        });
        return option ? option.label : value;
    }

    /**
     * Update active state for options
     */
    function updateActiveStates(instance) {
        var currentValue = RSL.FilterBus.getValue(instance.config.key);

        instance.optionElements.forEach(function(el) {
            var value = el.getAttribute('data-filter-value');
            var isActive = false;

            if (instance.config.multi && Array.isArray(currentValue)) {
                isActive = currentValue.includes(value);
            } else {
                isActive = currentValue === value;
            }

            el.setAttribute('aria-pressed', String(isActive));
            el.classList.toggle('active', isActive);

            // Update badge count if visible
            var badge = el.querySelector('.rsl-filter-badge');
            if (badge && instance.config.showCount) {
                // Count will be updated by subscriber
            }
        });

        // Update clear button visibility
        if (instance.clearBtn) {
            var hasValue = currentValue !== null && currentValue !== undefined &&
                           currentValue !== '' &&
                           (!Array.isArray(currentValue) || currentValue.length > 0);
            instance.clearBtn.setAttribute('data-visible', String(hasValue));
        }

        // Update container attribute
        instance.element.setAttribute('data-has-active', String(
            currentValue !== null && currentValue !== undefined &&
            currentValue !== '' &&
            (!Array.isArray(currentValue) || currentValue.length > 0)
        ));
    }

    /**
     * Handle option click
     */
    function handleOptionClick(instance, optionEl, event) {
        event.preventDefault();

        var value = optionEl.getAttribute('data-filter-value');
        var currentValue = RSL.FilterBus.getValue(instance.config.key);

        if (instance.config.multi) {
            // Multi-select mode
            var values = Array.isArray(currentValue) ? currentValue.slice() : [];
            var index = values.indexOf(value);

            if (index > -1) {
                values.splice(index, 1);
            } else {
                values.push(value);
            }

            RSL.FilterBus.publish(instance.config.key, values.length > 0 ? values : null, {
                source: 'filter-' + instance.config.key
            });

            // Announce
            if (index > -1) {
                announce(instance, getValueLabel(instance, value) + ' deselected');
            } else {
                announce(instance, getValueLabel(instance, value) + ' selected');
            }
        } else {
            // Single-select mode
            var newValue = currentValue === value ? null : value;

            RSL.FilterBus.publish(instance.config.key, newValue, {
                source: 'filter-' + instance.config.key
            });

            // Announce
            if (newValue) {
                announce(instance, 'Filter ' + (instance.config.label || instance.config.key) +
                        ' set to ' + getValueLabel(instance, newValue));
            } else {
                announce(instance, 'Filter ' + (instance.config.label || instance.config.key) + ' cleared');
            }
        }

        updateActiveStates(instance);
    }

    /**
     * Handle search input
     */
    function handleSearchInput(instance, inputEl) {
        var value = inputEl.value.trim();

        // Debounce
        if (instance.searchTimeout) {
            clearTimeout(instance.searchTimeout);
        }

        instance.searchTimeout = setTimeout(function() {
            RSL.FilterBus.publish(instance.config.key, value || null, {
                source: 'filter-' + instance.config.key
            });

            if (value) {
                announce(instance, 'Searching for ' + value);
            } else {
                announce(instance, 'Search cleared');
            }
        }, instance.config.debounce);
    }

    /**
     * Handle clear button click
     */
    function handleClear(instance) {
        RSL.FilterBus.clear(instance.config.key, {
            source: 'filter-' + instance.config.key
        });

        announce(instance, 'Filter ' + (instance.config.label || instance.config.key) + ' cleared');

        // Clear search input if exists
        if (instance.searchInput) {
            instance.searchInput.value = '';
        }

        updateActiveStates(instance);
    }

    /**
     * Handle keyboard navigation
     */
    function handleKeyboard(instance, event) {
        var options = instance.optionElements;
        if (!options || options.length === 0) return;

        var currentIndex = options.indexOf(document.activeElement);
        var newIndex = currentIndex;

        switch (event.key) {
            case 'ArrowRight':
            case 'ArrowDown':
                event.preventDefault();
                newIndex = currentIndex < options.length - 1 ? currentIndex + 1 : 0;
                break;

            case 'ArrowLeft':
            case 'ArrowUp':
                event.preventDefault();
                newIndex = currentIndex > 0 ? currentIndex - 1 : options.length - 1;
                break;

            case 'Home':
                event.preventDefault();
                newIndex = 0;
                break;

            case 'End':
                event.preventDefault();
                newIndex = options.length - 1;
                break;

            case 'Enter':
            case ' ':
                if (document.activeElement && options.includes(document.activeElement)) {
                    event.preventDefault();
                    handleOptionClick(instance, document.activeElement, event);
                }
                return;

            default:
                return;
        }

        if (newIndex !== currentIndex && options[newIndex]) {
            options[newIndex].focus();
        }
    }

    /**
     * Build filter options from child elements
     */
    function buildOptionsFromDOM(instance) {
        var optionEls = instance.element.querySelectorAll('[data-filter-value]');
        instance.options = [];
        instance.optionElements = [];

        optionEls.forEach(function(el) {
            var value = el.getAttribute('data-filter-value');
            var label = el.getAttribute('data-filter-label') || el.textContent.trim();
            var count = el.getAttribute('data-filter-count');

            instance.options.push({
                value: value,
                label: label,
                count: count ? parseInt(count, 10) : null
            });

            // Ensure proper ARIA
            if (!el.hasAttribute('role')) {
                el.setAttribute('role', 'button');
            }
            if (!el.hasAttribute('tabindex')) {
                el.setAttribute('tabindex', '0');
            }
            if (!el.hasAttribute('aria-pressed')) {
                el.setAttribute('aria-pressed', 'false');
            }
            // Add descriptive aria-label for screen readers
            if (!el.hasAttribute('aria-label')) {
                el.setAttribute('aria-label', 'Filter by ' + label);
            }

            // Add class
            el.classList.add('rsl-filter-option');

            // Add badge if showCount
            if (instance.config.showCount && count !== null) {
                var badge = el.querySelector('.rsl-filter-badge');
                if (!badge) {
                    badge = document.createElement('span');
                    badge.className = 'rsl-filter-badge';
                    badge.textContent = count;
                    el.appendChild(badge);
                }
            }

            // Event listeners
            el.addEventListener('click', function(e) {
                handleOptionClick(instance, el, e);
            });

            el.addEventListener('keydown', function(e) {
                if (e.key === 'Enter' || e.key === ' ') {
                    e.preventDefault();
                    handleOptionClick(instance, el, e);
                }
            });

            instance.optionElements.push(el);
        });
    }

    /**
     * Build search input
     */
    function buildSearchInput(instance) {
        var wrapper = document.createElement('div');
        wrapper.className = 'rsl-filter-search';

        var input = document.createElement('input');
        input.type = 'text';
        input.className = 'rsl-filter-search-input';
        input.placeholder = instance.config.placeholder;
        input.setAttribute('aria-label', instance.config.label || 'Search filter');

        var icon = document.createElement('span');
        icon.className = 'rsl-filter-search-icon';
        icon.innerHTML = '<i class="fas fa-search"></i>';

        var clearBtn = document.createElement('button');
        clearBtn.type = 'button';
        clearBtn.className = 'rsl-filter-search-clear';
        clearBtn.setAttribute('aria-label', 'Clear search');
        clearBtn.innerHTML = '<i class="fas fa-times"></i>';

        clearBtn.addEventListener('click', function() {
            input.value = '';
            RSL.FilterBus.clear(instance.config.key, {
                source: 'filter-' + instance.config.key
            });
            input.focus();
            announce(instance, 'Search cleared');
        });

        input.addEventListener('input', function() {
            handleSearchInput(instance, input);
            clearBtn.setAttribute('data-visible', input.value.length > 0 ? 'true' : 'false');
        });

        wrapper.appendChild(input);
        wrapper.appendChild(icon);
        wrapper.appendChild(clearBtn);

        instance.element.appendChild(wrapper);
        instance.searchInput = input;
    }

    /**
     * Build dropdown
     */
    function buildDropdown(instance) {
        var wrapper = document.createElement('div');
        wrapper.className = 'rsl-filter-dropdown';

        var trigger = document.createElement('button');
        trigger.type = 'button';
        trigger.className = 'rsl-filter-dropdown-trigger';
        trigger.setAttribute('aria-haspopup', 'listbox');
        trigger.setAttribute('aria-expanded', 'false');

        var triggerText = document.createElement('span');
        triggerText.className = 'rsl-filter-dropdown-text';
        triggerText.textContent = instance.config.placeholder || 'Select...';

        var arrow = document.createElement('span');
        arrow.className = 'rsl-filter-dropdown-arrow';
        arrow.innerHTML = '<i class="fas fa-chevron-down"></i>';

        trigger.appendChild(triggerText);
        trigger.appendChild(arrow);

        var menu = document.createElement('div');
        menu.className = 'rsl-filter-dropdown-menu';
        menu.setAttribute('role', 'listbox');

        // Build options
        instance.options.forEach(function(opt) {
            var option = document.createElement('button');
            option.type = 'button';
            option.className = 'rsl-filter-dropdown-option';
            option.setAttribute('role', 'option');
            option.setAttribute('data-filter-value', opt.value);
            option.setAttribute('aria-label', 'Filter by ' + opt.label);
            option.textContent = opt.label;

            option.addEventListener('click', function(e) {
                e.preventDefault();
                handleOptionClick(instance, option, e);
                triggerText.textContent = opt.label;
                closeDropdown();
            });

            menu.appendChild(option);
            instance.optionElements.push(option);
        });

        wrapper.appendChild(trigger);
        wrapper.appendChild(menu);

        // Dropdown toggle
        function openDropdown() {
            trigger.setAttribute('aria-expanded', 'true');
            menu.setAttribute('data-open', 'true');
            var firstOption = menu.querySelector('.rsl-filter-dropdown-option');
            if (firstOption) firstOption.focus();
        }

        function closeDropdown() {
            trigger.setAttribute('aria-expanded', 'false');
            menu.setAttribute('data-open', 'false');
        }

        trigger.addEventListener('click', function() {
            var isOpen = trigger.getAttribute('aria-expanded') === 'true';
            if (isOpen) {
                closeDropdown();
            } else {
                openDropdown();
            }
        });

        // Close on outside click
        document.addEventListener('click', function(e) {
            if (!wrapper.contains(e.target)) {
                closeDropdown();
            }
        });

        // Keyboard navigation
        wrapper.addEventListener('keydown', function(e) {
            if (e.key === 'Escape') {
                closeDropdown();
                trigger.focus();
            }
        });

        instance.element.appendChild(wrapper);
        instance.dropdownTrigger = trigger;
        instance.dropdownTriggerText = triggerText;
    }

    /**
     * Initialize a filter instance
     */
    function initInstance(element) {
        if (instances.has(element)) {
            return instances.get(element);
        }

        var config = getConfig(element);

        if (!config.key) {
            console.error('[RSL.Filter] Missing required data-filter-key attribute');
            return null;
        }

        var instance = {
            element: element,
            config: config,
            options: [],
            optionElements: [],
            liveRegion: null,
            clearBtn: null,
            searchInput: null,
            dropdownTrigger: null,
            searchTimeout: null
        };

        // Add ARIA attributes to container
        element.setAttribute('role', 'group');
        if (config.label) {
            element.setAttribute('aria-label', config.label);
        }

        // Create live region for announcements
        instance.liveRegion = createLiveRegion(element);

        // Build based on style
        if (config.style === 'search') {
            buildSearchInput(instance);
        } else if (config.style === 'dropdown') {
            // Build options array from data attributes or children
            var optionEls = element.querySelectorAll('[data-filter-value]');
            optionEls.forEach(function(el) {
                instance.options.push({
                    value: el.getAttribute('data-filter-value'),
                    label: el.getAttribute('data-filter-label') || el.textContent.trim()
                });
            });
            // Clear existing children that will be replaced
            while (element.firstChild) {
                element.removeChild(element.firstChild);
            }
            instance.liveRegion = createLiveRegion(element);
            buildDropdown(instance);
        } else {
            // Pills, buttons, chips, etc - use DOM children
            buildOptionsFromDOM(instance);
        }

        // Add clear button if enabled
        if (config.showClear && config.style !== 'search') {
            var clearBtn = document.createElement('button');
            clearBtn.type = 'button';
            clearBtn.className = 'rsl-filter-clear';
            clearBtn.setAttribute('aria-label', 'Clear filter');
            clearBtn.innerHTML = '<i class="fas fa-times"></i> Clear';
            clearBtn.setAttribute('data-visible', 'false');

            clearBtn.addEventListener('click', function() {
                handleClear(instance);
            });

            element.appendChild(clearBtn);
            instance.clearBtn = clearBtn;
        }

        // Keyboard navigation
        element.addEventListener('keydown', function(e) {
            handleKeyboard(instance, e);
        });

        // Set default value if provided
        if (config.defaultValue !== null && !RSL.FilterBus.getValue(config.key)) {
            RSL.FilterBus.publish(config.key, config.defaultValue, {
                source: 'filter-' + config.key + '-default',
                silent: true
            });
        }

        // Restore from localStorage if persist enabled
        if (config.persist) {
            var persistKey = 'rsl-filter-' + config.key;
            var stored = localStorage.getItem(persistKey);
            if (stored) {
                try {
                    var value = JSON.parse(stored);
                    RSL.FilterBus.publish(config.key, value, {
                        source: 'filter-' + config.key + '-restore',
                        silent: true
                    });
                } catch (e) {
                    // Ignore parse errors
                }
            }

            // Subscribe to save changes
            RSL.FilterBus.subscribe('persist-' + config.key, function(state) {
                localStorage.setItem(persistKey, JSON.stringify(state[config.key] || null));
            }, { keys: [config.key] });
        }

        // Initial state update
        updateActiveStates(instance);

        // Subscribe to FilterBus for external updates
        RSL.FilterBus.subscribe('filter-ui-' + config.key, function() {
            updateActiveStates(instance);
        }, { keys: [config.key] });

        instances.set(element, instance);

        // Dispatch ready event
        var readyEvent = new CustomEvent('rsl-filter-ready', {
            bubbles: true,
            detail: { key: config.key, instance: instance }
        });
        element.dispatchEvent(readyEvent);

        return instance;
    }

    /**
     * Public API
     */
    window.RSL.Filter = {

        /**
         * Initialize all filters on page
         */
        init: function() {
            var filters = document.querySelectorAll('[data-rsl-filter]');
            filters.forEach(function(el) {
                if (!instances.has(el)) {
                    initInstance(el);
                }
            });
        },

        /**
         * Create a filter instance
         * @param {HTMLElement|string} element - Element or selector
         * @param {Object} [options] - Configuration options
         * @returns {Object} Filter instance
         */
        create: function(element, options) {
            if (typeof element === 'string') {
                element = document.querySelector(element);
            }

            if (!element) {
                console.error('[RSL.Filter] Element not found');
                return null;
            }

            // Apply options as data attributes
            if (options) {
                Object.keys(options).forEach(function(key) {
                    var attrName = 'data-filter-' + key.replace(/([A-Z])/g, '-$1').toLowerCase();
                    element.setAttribute(attrName,
                        typeof options[key] === 'object' ? JSON.stringify(options[key]) : options[key]
                    );
                });
            }

            return initInstance(element);
        },

        /**
         * Destroy a filter instance
         * @param {HTMLElement|string} element - Element or selector
         */
        destroy: function(element) {
            if (typeof element === 'string') {
                element = document.querySelector(element);
            }

            var instance = instances.get(element);
            if (instance) {
                // Unsubscribe
                RSL.FilterBus.unsubscribe('filter-ui-' + instance.config.key);
                if (instance.config.persist) {
                    RSL.FilterBus.unsubscribe('persist-' + instance.config.key);
                }

                instances.delete(element);
            }
        },

        /**
         * Get instance for element
         * @param {HTMLElement|string} element
         * @returns {Object|null}
         */
        getInstance: function(element) {
            if (typeof element === 'string') {
                element = document.querySelector(element);
            }
            return instances.get(element) || null;
        },

        /**
         * Set filter value programmatically
         * @param {string} key - Filter key
         * @param {*} value - Filter value
         */
        setValue: function(key, value) {
            RSL.FilterBus.publish(key, value, { source: 'api' });
        },

        /**
         * Get filter value
         * @param {string} key - Filter key
         * @returns {*}
         */
        getValue: function(key) {
            return RSL.FilterBus.getValue(key);
        },

        /**
         * Clear a filter
         * @param {string} key - Filter key
         */
        clear: function(key) {
            RSL.FilterBus.clear(key, { source: 'api' });
        },

        /**
         * Clear all filters
         */
        clearAll: function() {
            RSL.FilterBus.clearAll({ source: 'api' });
        },

        /**
         * Check if any filters are active
         * @returns {boolean}
         */
        hasActiveFilters: function() {
            return RSL.FilterBus.hasActiveFilters();
        },

        /**
         * Get all active filter values
         * @returns {Object}
         */
        getActiveFilters: function() {
            return RSL.FilterBus.getState();
        }
    };

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

        // Dispatch global ready event
        document.dispatchEvent(new CustomEvent('rsl-filter-bus-ready', {
            bubbles: true,
            detail: { FilterBus: RSL.FilterBus, Filter: RSL.Filter }
        }));
    });

})();
