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 { computePosition, autoUpdate, offset, flip, shift, arrow as arrowMiddleware } from '../../../utils/positioning/index.js';
import { popoverTemplate } from './popover.template.js';
import { popoverStyles } from './popover.styles.js';
/**
 * ml-popover - Popover component that shows on trigger click
 *
 * @example
 * ```html
 * <ml-popover placement="bottom">
 *   <button slot="trigger">Open</button>
 *   <p>Popover content here</p>
 * </ml-popover>
 *
 * <ml-popover placement="bottom-start" manual>
 *   <button slot="trigger">Open</button>
 *   <div>
 *     <p>Locked content</p>
 *     <button>Close me manually</button>
 *   </div>
 * </ml-popover>
 * ```
 *
 * @slot trigger - The element that toggles the popover
 * @slot default - The popover content
 */
let PopoverComponent = class PopoverComponent {
    constructor() {
        /** Popover placement relative to trigger */
        this.placement = 'bottom';
        /** Gap between trigger and popover in px */
        this.offset = 8;
        /** When true, uses popover="manual" (no light-dismiss) */
        this.manual = false;
        /** When true, shows an arrow pointing to the trigger */
        this.arrow = false;
        /** Current open state */
        this.isOpen = false;
        this._cleanupAutoUpdate = null;
        /** Toggle the popover */
        this.toggle = () => {
            const popoverEl = this.getPopoverEl();
            if (popoverEl) {
                popoverEl.togglePopover();
            }
        };
        this.handleToggle = (event) => {
            const toggleEvent = event;
            if (toggleEvent.newState === 'open') {
                this.isOpen = true;
                this.startPositioning();
            }
            else {
                this.isOpen = false;
                this._cleanupAutoUpdate?.();
                this._cleanupAutoUpdate = null;
            }
        };
    }
    onCreate() {
        const popoverEl = this.getPopoverEl();
        if (popoverEl) {
            popoverEl.addEventListener('toggle', this.handleToggle);
        }
    }
    onDestroy() {
        this._cleanupAutoUpdate?.();
        const popoverEl = this.getPopoverEl();
        if (popoverEl) {
            popoverEl.removeEventListener('toggle', this.handleToggle);
        }
    }
    /** Open the popover */
    open() {
        const popoverEl = this.getPopoverEl();
        if (popoverEl && !this.isOpen) {
            popoverEl.showPopover();
        }
    }
    /** Close the popover */
    close() {
        const popoverEl = this.getPopoverEl();
        if (popoverEl && this.isOpen) {
            popoverEl.hidePopover();
        }
    }
    startPositioning() {
        const triggerEl = this.getTriggerEl();
        const popoverEl = this.getPopoverEl();
        if (!triggerEl || !popoverEl)
            return;
        const update = () => this.updatePosition(triggerEl, popoverEl);
        this._cleanupAutoUpdate?.();
        this._cleanupAutoUpdate = autoUpdate(triggerEl, popoverEl, update);
    }
    updatePosition(triggerEl, popoverEl) {
        const arrowEl = this.arrow ? this.elementRef.shadowRoot?.querySelector('.ml-popover__arrow') : null;
        const middleware = [offset(this.offset), flip(), shift({ padding: 8 })];
        if (arrowEl) {
            middleware.push(arrowMiddleware({ element: arrowEl, padding: 8 }));
        }
        const { x, y, placement, middlewareData } = computePosition(triggerEl, popoverEl, {
            placement: this.placement,
            middleware
        });
        popoverEl.style.left = `${x}px`;
        popoverEl.style.top = `${y}px`;
        popoverEl.dataset.placement = placement;
        if (arrowEl && middlewareData.arrow) {
            this.positionArrow(arrowEl, placement, middlewareData.arrow);
        }
    }
    positionArrow(arrowEl, placement, arrowData) {
        const side = placement.split('-')[0];
        arrowEl.style.left = arrowData.x === undefined ? '' : `${arrowData.x}px`;
        arrowEl.style.right = '';
        arrowEl.style.top = arrowData.y === undefined ? '' : `${arrowData.y}px`;
        arrowEl.style.bottom = '';
        if (side === 'top') {
            arrowEl.style.bottom = '-4px';
        }
        if (side === 'bottom') {
            arrowEl.style.top = '-4px';
        }
        if (side === 'left') {
            arrowEl.style.right = '-4px';
        }
        if (side === 'right') {
            arrowEl.style.left = '-4px';
        }
    }
    getTriggerEl() {
        return this.elementRef.shadowRoot?.querySelector('.ml-popover__trigger');
    }
    getPopoverEl() {
        return this.elementRef.shadowRoot?.querySelector('.ml-popover__content');
    }
};
PopoverComponent = __decorate([
    MelodicComponent({
        selector: 'ml-popover',
        template: popoverTemplate,
        styles: popoverStyles,
        attributes: ['placement', 'offset', 'manual', 'arrow']
    })
], PopoverComponent);
export { PopoverComponent };
