/**
 * Copyright Aquera Inc 2023
 *
 * This source code is licensed under the BSD-3-Clause license found in the
 * LICENSE file in the root directory of this source tree.
 */
import { __decorate } from "tslib";
import { html, } from 'lit-element';
import { customElement, property, state } from 'lit/decorators.js';
import { styles } from './nile-popover.css';
import NileElement from '../internal/nile-element';
import { watch } from '../internal/watch';
import { PopoverPortalManager } from './portal-manager';
import { VisibilityManager } from '../utilities/visibility-manager.js';
/**
 * Nile icon component.
 *
 * @tag nile-popover
 *
 */
let NilePopover = class NilePopover extends NileElement {
    constructor() {
        super(...arguments);
        /**
         * The preferred placement of the popover. Note that the actual placement may vary as needed to keep the tooltip
         * inside of the viewport.
         */
        this.placement = 'top';
        /** The distance in pixels from which to offset the popover away from its target. */
        this.distance = 18;
        this.preventOverlayClose = false;
        this.arrow = true;
        /** Gives the title to the popover */
        this.title = '';
        this.open = false;
        this.isShow = false;
        this.arrowPlacement = 'anchor';
        this.portalManager = null;
        this.enableVisibilityEffect = false;
        this.enableTabClose = false;
        /**
         * Enable this option to prevent the panel from being clipped when the component is placed inside a container with
         * `overflow: auto|scroll`. Hoisting uses a fixed positioning strategy that works in many, but not all, scenarios.
         */
        this.hoist = false;
        /**
         * Enable portal mode to render the popover content in a portal outside the component's DOM tree.
         * This provides better positioning control and prevents clipping issues in complex layouts.
         */
        this.portal = false;
        this.flip = false;
        this.handleClick = () => {
            this.isShow = !this.isShow;
            const allPopovers = document.querySelectorAll('nile-popover');
            allPopovers.forEach(popover => {
                if (popover !== this) {
                    popover.isShow = false;
                }
            });
        };
        this.handleDocumentClick = () => {
            if (this.isShow && !this.preventOverlayClose) {
                this.isShow = false;
            }
        };
        /* #endregion */
    }
    /**
     * The styles for Popover
     * @remarks If you are extending this class you can extend the base styles with super. Eg `return [super(), myCustomStyles]`
     */
    static get styles() {
        return [styles];
    }
    /* #endregion */
    /* #region Methods */
    /**
     * Render method
     * @slot This is a slot test
     */
    connectedCallback() {
        super.connectedCallback();
        this.emit('nile-init');
        document.addEventListener('click', this.handleDocumentClick);
        requestAnimationFrame(() => {
            if (this.portal && !this.portalManager) {
                this.portalManager = new PopoverPortalManager(this);
            }
        });
    }
    disconnectedCallback() {
        super.disconnectedCallback();
        this.emit('nile-destroy');
        this.visibilityManager?.cleanup();
        document.removeEventListener('click', this.handleDocumentClick);
        if (this.portalManager) {
            this.portalManager.cleanupPortalAppend();
            this.portalManager = null;
        }
    }
    async firstUpdated(_changed) {
        await this.updateComplete;
        const anchorSlot = this.renderRoot.querySelector('slot[name="anchor"]');
        const anchorEl = anchorSlot?.assignedElements({ flatten: true })[0];
        this.visibilityManager = new VisibilityManager({
            host: this,
            target: anchorEl || null,
            enableVisibilityEffect: this.enableVisibilityEffect,
            enableTabClose: this.enableTabClose,
            isOpen: () => this.isShow,
            onAnchorOutOfView: () => {
                this.isShow = false;
                this.emit('nile-visibility-change', {
                    visible: false,
                    reason: 'anchor-out-of-view',
                });
            },
            onDocumentHidden: () => {
                this.isShow = false;
                this.emit('nile-visibility-change', {
                    visible: false,
                    reason: 'document-hidden',
                });
            },
            emit: (event, detail) => this.emit(`nile-${event}`, detail),
        });
    }
    updated(_changedProperties) {
        if (_changedProperties.has('open')) {
            this.isShow = this.open;
        }
        if (_changedProperties.has('portal')) {
            if (this.portal && !this.portalManager) {
                this.portalManager = new PopoverPortalManager(this);
            }
            else if (!this.portal && this.portalManager) {
                this.portalManager.cleanupPortalAppend();
                this.portalManager = null;
            }
        }
    }
    handleShowHide() {
        if (this.isShow) {
            this.emit('nile-show');
            this.visibilityManager?.setup();
            if (this.portal && this.portalManager) {
                this.portalManager.setupPortalAppend();
            }
            else if (this.portal && !this.portalManager) {
                this.portalManager = new PopoverPortalManager(this);
                this.portalManager.setupPortalAppend();
            }
        }
        else {
            this.emit('nile-hide');
            this.visibilityManager?.cleanup();
            if (this.portal && this.portalManager) {
                this.portalManager.cleanupPortalAppend();
            }
        }
    }
    render() {
        const shouldRenderContent = this.isShow && !(this.portal && this.portalManager);
        return html `
      <nile-popup
        active
        .arrow="${this.arrow && this.isShow && !this.portal}"
        distance="${this.distance}"
        placement="${this.placement}"
        @click=${(e) => e.stopPropagation()}
        arrowPlacement="${this.arrowPlacement}"
        .flip="${this.flip}"
        shift
        strategy=${this.hoist ? 'fixed' : 'absolute'}
      >
        <slot
          slot="anchor"
          name="anchor"
          aria-describedby="tooltip"
          @click=${this.handleClick}
        ></slot>
        ${shouldRenderContent
            ? html ` <div part="popover" class="popover__box">
              <slot name="title" class="popover__title">${this.title}</slot>
              <slot part="base"></slot>
              <slot name="action" class="popover__action"> </slot>
            </div>`
            : html ``}
      </nile-popup>
    `;
    }
    updatePortalContent() {
        if (this.portalManager) {
            this.portalManager.updatePortalAppendPosition();
        }
    }
    forceReposition() {
        if (this.portalManager) {
            this.portalManager.forceReposition();
        }
    }
    getCurrentPlacement() {
        if (this.portalManager) {
            return this.portalManager.getCurrentPlacement();
        }
        return this.placement;
    }
    isPositioningOptimal() {
        if (this.portalManager) {
            return this.portalManager.isPositioningOptimal();
        }
        return true;
    }
};
__decorate([
    property()
], NilePopover.prototype, "placement", void 0);
__decorate([
    property({ type: Number })
], NilePopover.prototype, "distance", void 0);
__decorate([
    property({ type: Boolean, reflect: true })
], NilePopover.prototype, "preventOverlayClose", void 0);
__decorate([
    property({ type: Boolean, attribute: 'arrow' })
], NilePopover.prototype, "arrow", void 0);
__decorate([
    property({ type: String })
], NilePopover.prototype, "title", void 0);
__decorate([
    property({ type: Boolean })
], NilePopover.prototype, "open", void 0);
__decorate([
    state()
], NilePopover.prototype, "isShow", void 0);
__decorate([
    property({ attribute: 'arrow-placement' })
], NilePopover.prototype, "arrowPlacement", void 0);
__decorate([
    property({ type: Boolean, reflect: true })
], NilePopover.prototype, "enableVisibilityEffect", void 0);
__decorate([
    property({ type: Boolean, reflect: true })
], NilePopover.prototype, "enableTabClose", void 0);
__decorate([
    property({ type: Boolean })
], NilePopover.prototype, "hoist", void 0);
__decorate([
    property({ type: Boolean })
], NilePopover.prototype, "portal", void 0);
__decorate([
    property({ type: Boolean })
], NilePopover.prototype, "flip", void 0);
__decorate([
    watch('isShow')
], NilePopover.prototype, "handleShowHide", null);
NilePopover = __decorate([
    customElement('nile-popover')
], NilePopover);
export { NilePopover };
export default NilePopover;
//# sourceMappingURL=nile-popover.js.map