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 { LitElement } from 'lit';
import { property } from 'lit/decorators.js';
import { EventEmitterMixin } from '../../util/EventEmitterMixin.js';
import { ReadyMixin } from '../../util/ReadyMixin.js';
// Tailwind content scanning requires complete class names (no template literals).
const POSITION_CLASSES = {
    top: 'btu-popover-top',
    bottom: 'btu-popover-bottom',
    left: 'btu-popover-left',
    right: 'btu-popover-right',
};
const OFFSET_CLASSES = {
    sm: 'btu-popover-offset-sm',
    md: 'btu-popover-offset-md',
    lg: 'btu-popover-offset-lg',
    xl: 'btu-popover-offset-xl',
};
/**
 * A popover component for displaying rich interactive content anchored to a trigger element.
 *
 * Uses the native HTML Popover API for top-layer rendering, light dismiss (click-outside
 * and Escape for click triggers), and focus management. CSS anchor positioning handles
 * viewport-aware placement.
 *
 * For click triggers (`popover="auto"`), the browser provides:
 * - Light dismiss (Escape key and click-outside)
 * - Top-layer rendering (no z-index needed)
 * - Focus restoration on close
 * - `autofocus` support — add `autofocus` to an element inside `slot="content"`
 *   to have it receive focus when the popover opens
 *
 * @element btu-popover
 *
 * @fires {CustomEvent} btu-popover-show - Fired when the popover opens
 * @fires {CustomEvent} btu-popover-hide - Fired when the popover closes
 *
 * @cssprop --popover-color-background - Panel background color (default: var(--btu-theme-white))
 * @cssprop --popover-color-content - Panel text color (default: oklch(var(--btu-theme-gray-900)))
 * @cssprop --popover-border-radius - Panel corner radius (default: theme borderRadius.lg)
 * @cssprop --popover-offset - Gap between trigger and panel (default: 8px; see btu-popover-offset-{sm|md|lg|xl})
 * @cssprop --popover-arrow-size - Width/height of the pointer arrow (default: 8px)
 *
 * @slot trigger - The element that activates the popover
 * @slot content - Rich HTML content displayed inside the popover panel
 *
 * @example
 * ```html
 * <btu-popover position="bottom" trigger="click">
 *   <button slot="trigger">Open</button>
 *   <div slot="content">
 *     <h3>Title</h3>
 *     <p>Rich content here</p>
 *   </div>
 * </btu-popover>
 * ```
 */
export default class Popover extends EventEmitterMixin(ReadyMixin(LitElement)) {
    constructor() {
        super(...arguments);
        /**
         * Position relative to the trigger element.
         * Auto-flips when constrained by the viewport.
         * @attr
         */
        this.position = 'bottom';
        /**
         * How the popover is activated.
         * - 'click': Toggle on click with light dismiss
         * - 'hover': Show on mouseenter with delay
         * - 'focus': Show on focusin
         * @attr
         */
        this.trigger = 'click';
        /**
         * Show delay in milliseconds (hover trigger only).
         * @attr
         */
        this.delay = 300;
        /**
         * Gap between trigger and popover (sm=4px, md=8px, lg=12px, xl=16px).
         * @attr
         */
        this.offset = null;
        /**
         * Hide the arrow pseudo-element.
         * @attr
         */
        this.noArrow = false;
        /**
         * Programmatic open/close state (reflected).
         * @attr
         */
        this.open = false;
        /**
         * Accessible label for the popover panel (applied as aria-label on the dialog).
         * @attr panel-label
         */
        this.panelLabel = '';
        /** @internal */
        this._panelEl = null;
        /** @internal */
        this._panelId = `btu-popover-${crypto.randomUUID()}`;
        /** @internal */
        this._anchorName = `--btu-popover-trigger-${crypto.randomUUID()}`;
        /** @internal */
        this._showTimer = null;
        /** @internal */
        this._hideTimer = null;
        /** @internal */
        this._isVisible = false;
        /** @internal */
        this.initialClasses = [];
        /** @internal bound listeners */
        this._onTriggerMouseEnter = this._handleTriggerMouseEnter.bind(this);
        this._onTriggerMouseLeave = this._handleTriggerMouseLeave.bind(this);
        this._onTriggerFocusIn = this._handleTriggerFocusIn.bind(this);
        this._onTriggerFocusOut = this._handleTriggerFocusOut.bind(this);
        this._onPanelMouseEnter = this._handlePanelMouseEnter.bind(this);
        this._onPanelMouseLeave = this._handlePanelMouseLeave.bind(this);
        this._onNativeToggle = this._handleNativeToggle.bind(this);
        this._onKeyDown = this._handleKeyDown.bind(this);
    }
    createRenderRoot() {
        return this;
    }
    connectedCallback() {
        super.connectedCallback();
        if (this.className) {
            this.initialClasses = this.className.split(' ').filter(c => c.trim());
        }
    }
    disconnectedCallback() {
        this._clearTimers();
        this._unbindTriggerListeners();
        this._unbindPanelListeners();
        document.removeEventListener('keydown', this._onKeyDown);
        if (this._panelEl) {
            try {
                this._panelEl.hidePopover();
            }
            catch (e) {
                if (!(e instanceof DOMException && e.name === 'InvalidStateError')) {
                    console.warn('[btu-popover] Failed to hide popover during disconnect:', e);
                }
            }
            this._panelEl.removeEventListener('toggle', this._onNativeToggle);
            this._panelEl.remove();
            this._panelEl = null;
        }
        this._isVisible = false;
        super.disconnectedCallback();
    }
    willUpdate() {
        const classes = [...this.initialClasses];
        this.className = classes.filter(Boolean).join(' ');
    }
    firstUpdated() {
        this._setupPanel();
        this._bindTriggerListeners();
        // If initially open, show immediately
        if (this.open) {
            this._show();
        }
    }
    updated(changedProperties) {
        super.updated(changedProperties);
        if (changedProperties.has('trigger') && changedProperties.get('trigger') !== undefined) {
            this._unbindTriggerListeners();
            this._bindTriggerListeners();
            // Update popover mode when trigger changes
            if (this._panelEl) {
                if (this._isVisible) {
                    this._hide();
                }
                this._panelEl.setAttribute('popover', this.trigger === 'click' ? 'auto' : 'manual');
            }
        }
        if (changedProperties.has('position') || changedProperties.has('noArrow') || changedProperties.has('offset')) {
            if (this._panelEl) {
                this._panelEl.className = this._buildPanelClasses();
            }
        }
        if (changedProperties.has('panelLabel') && this._panelEl) {
            if (this.panelLabel) {
                this._panelEl.setAttribute('aria-label', this.panelLabel);
            }
            else {
                this._panelEl.removeAttribute('aria-label');
            }
        }
        // Sync programmatic open/close
        if (changedProperties.has('open') && changedProperties.get('open') !== undefined) {
            if (this.open && !this._isVisible) {
                this._show();
            }
            else if (!this.open && this._isVisible) {
                this._hide();
            }
        }
    }
    /** @internal Creates the popover panel and moves slot="content" children into it */
    _setupPanel() {
        const triggerEl = this.querySelector('[slot="trigger"]');
        const contentEl = this.querySelector('[slot="content"]');
        if (!triggerEl) {
            console.warn('[btu-popover] Missing required slot="trigger" element.');
            return;
        }
        // Set anchor name on trigger element
        triggerEl.style.setProperty('anchor-name', this._anchorName);
        // Create panel
        this._panelEl = document.createElement('div');
        this._panelEl.id = this._panelId;
        this._panelEl.className = this._buildPanelClasses();
        this._panelEl.setAttribute('role', 'dialog');
        if (this.panelLabel) {
            this._panelEl.setAttribute('aria-label', this.panelLabel);
        }
        this._panelEl.setAttribute('data-popover-internal', '');
        this._panelEl.style.setProperty('position-anchor', this._anchorName);
        // Set native popover attribute
        this._panelEl.setAttribute('popover', this.trigger === 'click' ? 'auto' : 'manual');
        // Listen for native toggle events — single source of truth for state
        this._panelEl.addEventListener('toggle', this._onNativeToggle);
        // Move content into panel
        if (contentEl) {
            contentEl.removeAttribute('slot');
            contentEl.style.display = '';
            this._panelEl.appendChild(contentEl);
        }
        this.appendChild(this._panelEl);
        // Set up aria on trigger
        triggerEl.setAttribute('aria-expanded', 'false');
        triggerEl.setAttribute('aria-controls', this._panelId);
        // Bind panel listeners for hover trigger
        this._bindPanelListeners();
    }
    /** @internal */
    _buildPanelClasses() {
        const classes = ['btu-popover', POSITION_CLASSES[this.position]];
        if (this.offset && OFFSET_CLASSES[this.offset])
            classes.push(OFFSET_CLASSES[this.offset]);
        if (this.noArrow)
            classes.push('btu-popover-no-arrow');
        return classes.join(' ');
    }
    /** @internal */
    _getTriggerEl() {
        return this.querySelector('[slot="trigger"]');
    }
    /** @internal */
    _bindTriggerListeners() {
        const triggerEl = this._getTriggerEl();
        if (!triggerEl)
            return;
        if (this.trigger === 'click') {
            triggerEl.setAttribute('popovertarget', this._panelId);
        }
        if (this.trigger === 'hover') {
            triggerEl.addEventListener('mouseenter', this._onTriggerMouseEnter);
            triggerEl.addEventListener('mouseleave', this._onTriggerMouseLeave);
        }
        if (this.trigger === 'focus') {
            triggerEl.addEventListener('focusin', this._onTriggerFocusIn);
            triggerEl.addEventListener('focusout', this._onTriggerFocusOut);
        }
        // popover="manual" doesn't get browser Escape handling — add it ourselves
        if (this.trigger !== 'click') {
            document.addEventListener('keydown', this._onKeyDown);
        }
    }
    /** @internal */
    _unbindTriggerListeners() {
        const triggerEl = this._getTriggerEl();
        if (!triggerEl)
            return;
        triggerEl.removeAttribute('popovertarget');
        triggerEl.removeEventListener('mouseenter', this._onTriggerMouseEnter);
        triggerEl.removeEventListener('mouseleave', this._onTriggerMouseLeave);
        triggerEl.removeEventListener('focusin', this._onTriggerFocusIn);
        triggerEl.removeEventListener('focusout', this._onTriggerFocusOut);
        document.removeEventListener('keydown', this._onKeyDown);
    }
    /** @internal */
    _bindPanelListeners() {
        if (!this._panelEl)
            return;
        this._panelEl.addEventListener('mouseenter', this._onPanelMouseEnter);
        this._panelEl.addEventListener('mouseleave', this._onPanelMouseLeave);
    }
    /** @internal */
    _unbindPanelListeners() {
        if (!this._panelEl)
            return;
        this._panelEl.removeEventListener('mouseenter', this._onPanelMouseEnter);
        this._panelEl.removeEventListener('mouseleave', this._onPanelMouseLeave);
    }
    /** @internal */
    _show() {
        this._clearHideTimer();
        if (this._isVisible || !this._panelEl)
            return;
        try {
            this._panelEl.showPopover();
        }
        catch (e) {
            if (!(e instanceof DOMException && e.name === 'InvalidStateError')) {
                console.warn('[btu-popover] Failed to show popover:', e);
            }
        }
    }
    /** @internal */
    _hide() {
        this._clearTimers();
        if (!this._isVisible || !this._panelEl)
            return;
        try {
            this._panelEl.hidePopover();
        }
        catch (e) {
            if (!(e instanceof DOMException && e.name === 'InvalidStateError')) {
                console.warn('[btu-popover] Failed to hide popover:', e);
            }
        }
    }
    /** @internal Native toggle event — single source of truth for state changes */
    _handleNativeToggle(e) {
        const { newState } = e;
        if (newState === 'open') {
            this._isVisible = true;
            this.open = true;
            const triggerEl = this._getTriggerEl();
            if (triggerEl) {
                triggerEl.setAttribute('aria-expanded', 'true');
            }
            this.emit('btu-popover-show');
        }
        else {
            this._isVisible = false;
            this.open = false;
            const triggerEl = this._getTriggerEl();
            if (triggerEl) {
                triggerEl.setAttribute('aria-expanded', 'false');
                // Restore focus to trigger if focus was lost (e.g., programmatic close)
                if (document.activeElement === document.body) {
                    triggerEl.focus();
                }
            }
            this.emit('btu-popover-hide');
        }
    }
    /** @internal Escape dismisses for popover="manual" (hover/focus triggers) */
    _handleKeyDown(e) {
        if (e.key === 'Escape') {
            this._clearTimers();
            this._hide();
        }
    }
    /** @internal */
    _clearShowTimer() {
        if (this._showTimer !== null) {
            clearTimeout(this._showTimer);
            this._showTimer = null;
        }
    }
    /** @internal */
    _clearHideTimer() {
        if (this._hideTimer !== null) {
            clearTimeout(this._hideTimer);
            this._hideTimer = null;
        }
    }
    /** @internal */
    _clearTimers() {
        this._clearShowTimer();
        this._clearHideTimer();
    }
    /** @internal Hover trigger: show with delay */
    _handleTriggerMouseEnter() {
        this._clearTimers();
        this._showTimer = setTimeout(() => this._show(), this.delay);
    }
    /** @internal Hover trigger: hide with small delay for cursor travel */
    _handleTriggerMouseLeave() {
        this._clearTimers();
        this._hideTimer = setTimeout(() => this._hide(), 100);
    }
    /** @internal Focus trigger: show immediately */
    _handleTriggerFocusIn() {
        this._clearTimers();
        this._show();
    }
    /** @internal Focus trigger: hide immediately */
    _handleTriggerFocusOut() {
        this._clearTimers();
        this._hide();
    }
    /** @internal Keep popover open when hovering the panel (hover trigger) */
    _handlePanelMouseEnter() {
        if (this.trigger === 'hover') {
            this._clearTimers();
        }
    }
    /** @internal Hide when mouse leaves the panel (hover trigger) */
    _handlePanelMouseLeave() {
        if (this.trigger === 'hover') {
            this._clearTimers();
            this._hideTimer = setTimeout(() => this._hide(), 100);
        }
    }
}
__decorate([
    property({ attribute: 'position' })
], Popover.prototype, "position", void 0);
__decorate([
    property({ attribute: 'trigger' })
], Popover.prototype, "trigger", void 0);
__decorate([
    property({ attribute: 'delay', type: Number })
], Popover.prototype, "delay", void 0);
__decorate([
    property({ attribute: 'offset' })
], Popover.prototype, "offset", void 0);
__decorate([
    property({ attribute: 'no-arrow', type: Boolean })
], Popover.prototype, "noArrow", void 0);
__decorate([
    property({ attribute: 'open', type: Boolean, reflect: true })
], Popover.prototype, "open", void 0);
__decorate([
    property({ attribute: 'panel-label' })
], Popover.prototype, "panelLabel", void 0);
if (!customElements.get('btu-popover')) {
    customElements.define('btu-popover', Popover);
}
//# sourceMappingURL=Popover.js.map