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 { stepsTemplate } from './steps.template.js';
import { stepsStyles } from './steps.styles.js';
/**
 * ml-steps - Multi-step progress/wizard component
 *
 * @example Config array mode:
 * ```html
 * <ml-steps active="company" variant="circles" .steps=${stepConfigs}>
 *   <ml-step-panel value="details">Step 1 content</ml-step-panel>
 *   <ml-step-panel value="company">Step 2 content</ml-step-panel>
 * </ml-steps>
 * ```
 *
 * @example Slotted mode:
 * ```html
 * <ml-steps active="company" variant="numbered">
 *   <ml-step slot="step" value="details" label="Your details"></ml-step>
 *   <ml-step slot="step" value="company" label="Company"></ml-step>
 *   <ml-step-panel value="details">Content 1</ml-step-panel>
 *   <ml-step-panel value="company">Content 2</ml-step-panel>
 * </ml-steps>
 * ```
 *
 * @slot step - Step header elements (ml-step)
 * @slot default - Step panel content or router-outlet
 *
 * @fires ml:change - Emitted when active step changes
 */
let StepsComponent = class StepsComponent {
    constructor() {
        /** Currently active step value */
        this.active = '';
        /** Visual variant */
        this.variant = 'numbered';
        /** Layout orientation */
        this.orientation = 'horizontal';
        /** Connector line style */
        this.connector = 'solid';
        /** Accent color */
        this.color = 'primary';
        /** Compact dots mode */
        this.compact = false;
        /** Enable router integration */
        this.routed = false;
        /** Step configurations (alternative to slotted ml-step elements) */
        this.steps = [];
        /** Internal tracking of slotted steps */
        this._slottedSteps = [];
        /** Navigation event listener for routed mode */
        this._handleNavigation = this.onNavigation.bind(this);
        /** Handle step slot changes */
        this.handleStepSlotChange = (event) => {
            const slot = event.target;
            this._slottedSteps = slot.assignedElements({ flatten: true });
            // Set initial value if not set
            if (!this.active && this._slottedSteps.length > 0) {
                const firstStep = this._slottedSteps.find((step) => !step.hasAttribute('disabled'));
                if (firstStep) {
                    this.active = firstStep.getAttribute('value') || '';
                }
            }
            this.updateSlottedStepStates();
            this.updatePanelVisibility();
        };
        /** Handle step click (config mode) */
        this.handleStepClick = (stepValue, href) => {
            const step = this.getStepByValue(stepValue);
            if (step?.disabled)
                return;
            if (this.routed && href) {
                window.history.pushState({}, '', href);
                window.dispatchEvent(new PopStateEvent('popstate'));
            }
            this.active = stepValue;
            this.updateSlottedStepStates();
            this.updatePanelVisibility();
            this.elementRef.dispatchEvent(new CustomEvent('ml:change', {
                bubbles: true,
                composed: true,
                detail: { value: stepValue }
            }));
        };
        /** Handle slotted step click event */
        this.handleSlottedStepClick = (event) => {
            const { value, href } = event.detail;
            this.handleStepClick(value, href);
        };
        /** Handle keyboard navigation */
        this.handleKeyDown = (event) => {
            const allSteps = this.getAllSteps();
            const enabledSteps = allSteps.filter((s) => !s.disabled);
            const currentIndex = enabledSteps.findIndex((s) => s.value === this.active);
            let newIndex = currentIndex;
            const isVertical = this.orientation === 'vertical';
            switch (event.key) {
                case 'ArrowLeft':
                    if (isVertical)
                        return;
                    event.preventDefault();
                    newIndex = currentIndex > 0 ? currentIndex - 1 : enabledSteps.length - 1;
                    break;
                case 'ArrowRight':
                    if (isVertical)
                        return;
                    event.preventDefault();
                    newIndex = currentIndex < enabledSteps.length - 1 ? currentIndex + 1 : 0;
                    break;
                case 'ArrowUp':
                    if (!isVertical)
                        return;
                    event.preventDefault();
                    newIndex = currentIndex > 0 ? currentIndex - 1 : enabledSteps.length - 1;
                    break;
                case 'ArrowDown':
                    if (!isVertical)
                        return;
                    event.preventDefault();
                    newIndex = currentIndex < enabledSteps.length - 1 ? currentIndex + 1 : 0;
                    break;
                case 'Home':
                    event.preventDefault();
                    newIndex = 0;
                    break;
                case 'End':
                    event.preventDefault();
                    newIndex = enabledSteps.length - 1;
                    break;
                default:
                    return;
            }
            if (newIndex !== currentIndex && enabledSteps[newIndex]) {
                const step = enabledSteps[newIndex];
                this.handleStepClick(step.value, step.href);
                this.focusStep(step.value);
            }
        };
    }
    onCreate() {
        // Listen for step click events from slotted ml-step elements
        this.elementRef.addEventListener('ml:step-click', this.handleSlottedStepClick);
        if (this.routed) {
            window.addEventListener('NavigationEvent', this._handleNavigation);
            this.syncWithRoute();
        }
    }
    onRender() {
        this.updatePanelVisibility();
    }
    onDestroy() {
        this.elementRef.removeEventListener('ml:step-click', this.handleSlottedStepClick);
        if (this.routed) {
            window.removeEventListener('NavigationEvent', this._handleNavigation);
        }
    }
    /** Get status for a step based on its position relative to active */
    getStepStatus(stepValue) {
        const allSteps = this.getAllSteps();
        const activeIndex = allSteps.findIndex((s) => s.value === this.active);
        const stepIndex = allSteps.findIndex((s) => s.value === stepValue);
        if (stepIndex < activeIndex)
            return 'completed';
        if (stepIndex === activeIndex)
            return 'current';
        return 'upcoming';
    }
    /** Get current step index (1-based, for compact label) */
    getCurrentStepNumber() {
        const allSteps = this.getAllSteps();
        const index = allSteps.findIndex((s) => s.value === this.active);
        return index + 1;
    }
    /** Get total step count */
    getTotalSteps() {
        return this.getAllSteps().length;
    }
    /** Get all steps (from config or slotted) */
    getAllSteps() {
        if (this.steps.length > 0) {
            return this.steps;
        }
        return this._slottedSteps.map((el) => ({
            value: el.getAttribute('value') || '',
            label: el.getAttribute('label') || el.textContent || '',
            description: el.getAttribute('description') || undefined,
            icon: el.getAttribute('icon') || undefined,
            disabled: el.hasAttribute('disabled'),
            href: el.getAttribute('href') || undefined
        }));
    }
    /** Get step by value */
    getStepByValue(value) {
        return this.getAllSteps().find((s) => s.value === value);
    }
    /** Update attributes on slotted steps */
    updateSlottedStepStates() {
        const allSteps = this.getAllSteps();
        this._slottedSteps.forEach((step, index) => {
            const value = step.getAttribute('value') || '';
            const status = this.getStepStatus(value);
            step.setAttribute('status', status);
            step.setAttribute('variant', this.variant);
            step.setAttribute('connector', this.connector);
            step.setAttribute('color', this.color);
            step.setAttribute('orientation', this.orientation);
            step.setAttribute('step-number', String(index + 1));
            step.toggleAttribute('first', index === 0);
            step.toggleAttribute('last', index === allSteps.length - 1);
            step.toggleAttribute('compact', this.compact);
        });
    }
    /** Update panel visibility */
    updatePanelVisibility() {
        if (this.routed)
            return;
        const panels = this.elementRef.querySelectorAll('ml-step-panel');
        panels.forEach((panel) => {
            const isActive = panel.getAttribute('value') === this.active;
            panel.style.display = isActive ? '' : 'none';
        });
    }
    /** Focus a specific step button */
    focusStep(value) {
        const stepList = this.elementRef.shadowRoot?.querySelector('.ml-steps__list');
        const button = stepList?.querySelector(`[data-value="${value}"]`);
        button?.focus();
    }
    /** Sync active step with current route */
    syncWithRoute() {
        const path = window.location.pathname;
        const matchingStep = this.getAllSteps().find((step) => step.href && path.startsWith(step.href));
        if (matchingStep) {
            this.active = matchingStep.value;
            this.updateSlottedStepStates();
        }
    }
    /** Handle navigation events (routed mode) */
    onNavigation() {
        this.syncWithRoute();
    }
};
StepsComponent = __decorate([
    MelodicComponent({
        selector: 'ml-steps',
        template: stepsTemplate,
        styles: stepsStyles,
        attributes: ['active', 'variant', 'orientation', 'connector', 'color', 'compact', 'routed']
    })
], StepsComponent);
export { StepsComponent };
