var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
import { MelodicComponent } from '@melodicdev/core';
import { sidebarTemplate } from './sidebar.template.js';
import { sidebarStyles } from './sidebar.styles.js';
/**
 * ml-sidebar - App-level sidebar navigation component
 *
 * @example Slotted mode:
 * ```html
 * <ml-sidebar active="home">
 *   <div slot="header">Logo</div>
 *   <ml-sidebar-group label="GENERAL">
 *     <ml-sidebar-item icon="house" label="Home" value="home"></ml-sidebar-item>
 *   </ml-sidebar-group>
 * </ml-sidebar>
 * ```
 *
 * @example Config mode:
 * ```html
 * <ml-sidebar active="home" .navigation=${navGroups}></ml-sidebar>
 * ```
 *
 * @slot header - Logo/branding area
 * @slot search - Search input area
 * @slot default - Navigation content (groups and items)
 * @slot footer-nav - Footer navigation items
 * @slot feature - Feature promotion card
 * @slot user - User profile area
 *
 * @fires ml:change - Emitted when active item changes
 * @fires ml:item-click - Emitted when any item is clicked
 */
let SidebarComponent = class SidebarComponent {
    constructor() {
        /** Visual variant */
        this.variant = 'default';
        /** Currently active item value */
        this.active = '';
        /** Collapsed state (controlled by slim variant hover) */
        this.collapsed = false;
        /** Navigation config (alternative to slotted content) */
        this.navigation = [];
        /** Footer navigation config */
        this.footerNavigation = [];
        /** Debounce timer for hover */
        this._hoverTimer = null;
        /** Bound event handlers */
        this._handleItemClick = this.onItemClick.bind(this);
        this._handleMouseEnter = this.onMouseEnter.bind(this);
        this._handleMouseLeave = this.onMouseLeave.bind(this);
        /** Handle slotted items change */
        this.handleDefaultSlotChange = () => {
            this.updateItemStates();
        };
        /** Handle config item click */
        this.handleConfigItemClick = (value, href) => {
            this.activateItem(value, href);
        };
        /** Handle config submenu toggle */
        this.handleConfigToggle = (item) => {
            const next = new Set(this.expandedItems);
            if (next.has(item.value)) {
                next.delete(item.value);
            }
            else {
                next.add(item.value);
            }
            this.expandedItems = next;
        };
        /** Keyboard navigation */
        this.handleKeyDown = (event) => {
            const sidebar = this.elementRef.shadowRoot?.querySelector('.ml-sidebar__main');
            if (!sidebar)
                return;
            const focusable = Array.from(sidebar.querySelectorAll('.ml-sidebar__item-link:not([disabled]), button:not([disabled]), a'));
            const currentIndex = focusable.indexOf(event.target);
            let newIndex = currentIndex;
            switch (event.key) {
                case 'ArrowUp':
                    event.preventDefault();
                    newIndex = currentIndex > 0 ? currentIndex - 1 : focusable.length - 1;
                    break;
                case 'ArrowDown':
                    event.preventDefault();
                    newIndex = currentIndex < focusable.length - 1 ? currentIndex + 1 : 0;
                    break;
                case 'Home':
                    event.preventDefault();
                    newIndex = 0;
                    break;
                case 'End':
                    event.preventDefault();
                    newIndex = focusable.length - 1;
                    break;
                default:
                    return;
            }
            if (newIndex !== currentIndex && focusable[newIndex]) {
                focusable[newIndex].focus();
            }
        };
        /** Track expanded config items */
        this.expandedItems = new Set();
    }
    /** Check if search slot has content */
    get hasSearch() {
        return this.elementRef?.querySelector('[slot="search"]') !== null;
    }
    /** Check if feature slot has content */
    get hasFeature() {
        return this.elementRef?.querySelector('[slot="feature"]') !== null;
    }
    /** Check if user slot has content */
    get hasUser() {
        return this.elementRef?.querySelector('[slot="user"]') !== null;
    }
    onCreate() {
        // Set initial collapsed state based on variant
        if (this.variant === 'slim') {
            this.collapsed = true;
        }
        // Listen for item click events from children
        this.elementRef.addEventListener('ml:sidebar-item-click', this._handleItemClick);
        // Set up hover for slim variant
        if (this.variant === 'slim') {
            this.elementRef.addEventListener('mouseenter', this._handleMouseEnter);
            this.elementRef.addEventListener('mouseleave', this._handleMouseLeave);
        }
    }
    onRender() {
        this.updateItemStates();
    }
    onDestroy() {
        this.elementRef.removeEventListener('ml:sidebar-item-click', this._handleItemClick);
        this.elementRef.removeEventListener('mouseenter', this._handleMouseEnter);
        this.elementRef.removeEventListener('mouseleave', this._handleMouseLeave);
        if (this._hoverTimer) {
            clearTimeout(this._hoverTimer);
        }
    }
    /** Activate an item */
    activateItem(value, href) {
        this.active = value;
        this.updateItemStates();
        this.elementRef.dispatchEvent(new CustomEvent('ml:change', {
            bubbles: true,
            composed: true,
            detail: { value }
        }));
        this.elementRef.dispatchEvent(new CustomEvent('ml:item-click', {
            bubbles: true,
            composed: true,
            detail: { value, href }
        }));
    }
    /** Handle item click from slotted children */
    onItemClick(event) {
        const { value, href } = event.detail;
        this.activateItem(value, href);
    }
    /** Handle mouse enter for slim variant */
    onMouseEnter() {
        if (this.variant !== 'slim')
            return;
        if (this._hoverTimer)
            clearTimeout(this._hoverTimer);
        this._hoverTimer = setTimeout(() => {
            this.collapsed = false;
            this.updateItemStates();
        }, 150);
    }
    /** Handle mouse leave for slim variant */
    onMouseLeave() {
        if (this.variant !== 'slim')
            return;
        if (this._hoverTimer)
            clearTimeout(this._hoverTimer);
        this._hoverTimer = setTimeout(() => {
            this.collapsed = true;
            this.updateItemStates();
        }, 150);
    }
    /** Propagate active/collapsed state to slotted children */
    updateItemStates() {
        // Update slotted sidebar items
        const items = this.elementRef.querySelectorAll('ml-sidebar-item');
        items.forEach((item) => {
            const value = item.getAttribute('value') || '';
            item.toggleAttribute('active', value === this.active);
            item.toggleAttribute('collapsed', this.collapsed);
        });
        // Update slotted sidebar groups
        const groups = this.elementRef.querySelectorAll('ml-sidebar-group');
        groups.forEach((group) => {
            group.toggleAttribute('collapsed', this.collapsed);
        });
    }
};
SidebarComponent = __decorate([
    MelodicComponent({
        selector: 'ml-sidebar',
        template: sidebarTemplate,
        styles: sidebarStyles,
        attributes: ['variant', 'active']
    })
], SidebarComponent);
export { SidebarComponent };
