import {
  __decorateClass,
  __privateAdd,
  __privateGet,
  __privateMethod,
  __privateSet
} from "../../chunks/chunk.QU3DSPNU.js";
var _GdsPopover_instances, handleTriggerSlotChange_fn, _autoPositionCleanupFn, _isMobileViewport, _backdropEl, _handleCancel, _dispatchUiStateEvent, _handleCloseButton, registerTriggerEvents_fn, unregisterTriggerEvents_fn, setupTriggerAttributes_fn, registerAutoPositioning_fn, _handleTriggerKeyDown, _handleTriggerClick, _focusFirstSlottedChild, _handleClickOutside, _handlePageScroll;
import { localized, msg } from "@lit/localize";
import { property, query, state } from "lit/decorators.js";
import { classMap } from "lit/directives/class-map.js";
import {
  autoUpdate,
  computePosition,
  offset,
  shift
} from "@floating-ui/dom";
import { GdsElement } from "../../gds-element.js";
import { gdsCustomElement, html } from "../../scoping.js";
import { TransitionalStyles } from "../../transitional-styles.js";
import { watch, watchMediaQuery } from "../../utils/decorators/index.js";
import { IconCrossSmall } from "../icon/icons/cross-small.component.js";
import PopoverStyles from "./popover.styles.js";
function applyTriggerAriaAttributes(trigger, open, popupRole) {
  trigger.setAttribute("aria-expanded", String(open));
  const focusableNodeNames = ["A", "BUTTON", "INPUT", "TEXTAREA"];
  const isProbablyFocusable = trigger.nodeName.startsWith("GDS-") || focusableNodeNames.includes(trigger.nodeName);
  if (!isProbablyFocusable) {
    trigger.setAttribute("tabindex", "0");
    trigger.setAttribute("role", "button");
  }
  const ariaHasPopupAttr = trigger.nodeName.startsWith("GDS-") ? "gds-aria-haspopup" : "aria-haspopup";
  if (trigger.getAttribute(ariaHasPopupAttr) === null) {
    trigger.setAttribute(ariaHasPopupAttr, popupRole);
  }
}
let GdsPopover = class extends GdsElement {
  constructor() {
    super(...arguments);
    __privateAdd(this, _GdsPopover_instances);
    this.open = false;
    this.popupRole = "dialog";
    this.label = void 0;
    this.placement = "bottom-start";
    this.disableMobileStyles = false;
    this.disableScrollClose = false;
    this.autofocus = false;
    this.calcMinWidth = (referenceEl) => `${referenceEl.offsetWidth}px`;
    this.calcMaxWidth = (_referenceEl) => `auto`;
    this.calcMinHeight = (_referenceEl) => `auto`;
    this.calcMaxHeight = (_referenceEl) => `${window.innerHeight - 16}px`;
    this.nonmodal = false;
    this.floatingUIMiddleware = GdsPopover.DefaultMiddleware;
    this._trigger = void 0;
    this._anchor = void 0;
    this._isVirtKbVisible = false;
    // A function that removes the Floating UI auto positioning. This gets called when we switch to mobile view layout.
    __privateAdd(this, _autoPositionCleanupFn);
    __privateAdd(this, _isMobileViewport, false);
    __privateAdd(this, _backdropEl);
    __privateAdd(this, _handleCancel, () => {
      if (__privateGet(this, _dispatchUiStateEvent).call(this, "cancel")) this.open = false;
    });
    __privateAdd(this, _dispatchUiStateEvent, (reason) => {
      const toState = reason === "show" ? true : false;
      return this.dispatchCustomEvent("gds-ui-state", {
        detail: { open: toState, reason },
        bubbles: false,
        composed: false,
        cancelable: true
      });
    });
    __privateAdd(this, _handleCloseButton, (e) => {
      e.stopPropagation();
      e.preventDefault();
      if (__privateGet(this, _dispatchUiStateEvent).call(this, "close")) {
        this.open = false;
        setTimeout(() => this._trigger?.focus(), 250);
      }
    });
    /**
     * ArrowDown or ArrowUp on the trigger element will trigger the popover by default, and escape will close it.
     */
    __privateAdd(this, _handleTriggerKeyDown, (e) => {
      if (e.key === "ArrowDown" || e.key === "ArrowUp") {
        e.preventDefault();
        this.open = true;
        __privateGet(this, _dispatchUiStateEvent).call(this, "show");
      }
      if (e.key === "Escape" && this.open) {
        __privateGet(this, _handleCancel).call(this);
      }
    });
    __privateAdd(this, _handleTriggerClick, (e) => {
      e.preventDefault();
      if (__privateGet(this, _dispatchUiStateEvent).call(this, this.open ? "close" : "show"))
        this.open = !this.open;
    });
    /**
     * Move focus to the first slotted child.
     */
    __privateAdd(this, _focusFirstSlottedChild, () => {
      const firstSlottedChild = this._elDefaultSlot?.assignedElements()[0];
      this.updateComplete.then(() => {
        firstSlottedChild?.focus();
      });
    });
    __privateAdd(this, _handleClickOutside, (evt) => {
      const e = evt;
      const dialog = this._elDialog;
      const isNotEnterKey = e.clientX > 0 || e.clientY > 0;
      if (isNotEnterKey && dialog && this.open) {
        const rect = dialog.getBoundingClientRect();
        const isInDialog = rect.top <= e.clientY && e.clientY <= rect.top + rect.height && rect.left <= e.clientX && e.clientX <= rect.left + rect.width;
        if (!isInDialog && __privateGet(this, _dispatchUiStateEvent).call(this, "close")) {
          this.open = false;
        }
      }
    });
    __privateAdd(this, _handlePageScroll, () => {
      if (this.open && !this.disableScrollClose && window.innerWidth > 767 && __privateGet(this, _dispatchUiStateEvent).call(this, "close")) {
        this.open = false;
      }
    });
  }
  _handleTriggerRefChanged() {
    this.triggerRef?.then((el) => {
      if (el) this._trigger = el;
    });
  }
  _handleAnchorRefChanged() {
    this.anchorRef?.then((el) => {
      if (el) this._anchor = el;
    });
  }
  _handleTriggerChanged() {
    __privateMethod(this, _GdsPopover_instances, registerTriggerEvents_fn).call(this);
    __privateMethod(this, _GdsPopover_instances, setupTriggerAttributes_fn).call(this);
  }
  _handleAnchorChanged() {
    __privateMethod(this, _GdsPopover_instances, registerAutoPositioning_fn).call(this);
  }
  connectedCallback() {
    super.connectedCallback();
    TransitionalStyles.instance.apply(this, "gds-popover");
    __privateMethod(this, _GdsPopover_instances, registerTriggerEvents_fn).call(this);
    this._handleOpenChange();
    this.addEventListener("keydown", (e) => {
      if (e.key === "Escape" && this.open) {
        __privateGet(this, _handleCancel).call(this);
        e.stopPropagation();
        e.preventDefault();
      }
    });
    this.addEventListener("focusin", (e) => {
      const t = e.target;
      if (t === this) return;
      if (t.tagName === "INPUT" || t.tagName === "TEXTAREA") {
        this._isVirtKbVisible = true;
      } else {
        this._isVirtKbVisible = false;
      }
    });
    this.addEventListener("blurin", (_) => {
      this._isVirtKbVisible = false;
    });
  }
  disconnectedCallback() {
    super.disconnectedCallback();
    __privateMethod(this, _GdsPopover_instances, unregisterTriggerEvents_fn).call(this);
    window.removeEventListener("scroll", __privateGet(this, _handlePageScroll));
  }
  render() {
    return html`<slot
        name="trigger"
        @slotchange=${__privateMethod(this, _GdsPopover_instances, handleTriggerSlotChange_fn)}
      ></slot>
      <div ?hidden="${!this.open}">
        <dialog
          class="${classMap({
      "v-kb-visible": this._isVirtKbVisible,
      "use-modal-in-mobile": !this.disableMobileStyles,
      "has-backdrop": Boolean(this.backdrop && this.backdrop === "true")
    })}"
          ?inert="${!this.open}"
          @close=${() => this.open && __privateGet(this, _handleCancel).call(this)}
        >
          <header>
            <h2>${this.label}</h2>
            <gds-button
              @click=${__privateGet(this, _handleCloseButton)}
              class="close"
              label="${msg("Close")}"
              size="small"
              rank="tertiary"
            >
              <gds-icon-cross-small></gds-icon-cross-small>
            </gds-button>
          </header>
          <slot></slot>
        </dialog>
      </div>`;
  }
  _handleOpenChange() {
    const clickOutsideTarget = (this.nonmodal ? __privateGet(this, _backdropEl) : this._elDialog) || document;
    this.updateComplete.then(() => {
      this._trigger?.setAttribute("aria-expanded", String(this.open));
      if (this.open) {
        !this.nonmodal ? this._elDialog?.showModal() : this._elDialog?.setAttribute("open", "true");
        if (this.autofocus) {
          __privateGet(this, _focusFirstSlottedChild).call(this);
          setTimeout(() => __privateGet(this, _focusFirstSlottedChild).call(this), 250);
        }
        requestAnimationFrame(() => {
          if (__privateGet(this, _backdropEl)) __privateGet(this, _backdropEl).show = true;
        });
        setTimeout(
          () => clickOutsideTarget.addEventListener(
            "click",
            __privateGet(this, _handleClickOutside)
          ),
          0
        );
        window.addEventListener("scroll", __privateGet(this, _handlePageScroll), {
          passive: true
        });
      } else {
        this._elDialog?.close();
        clickOutsideTarget.removeEventListener(
          "click",
          __privateGet(this, _handleClickOutside)
        );
        window.removeEventListener("scroll", __privateGet(this, _handlePageScroll));
        if (__privateGet(this, _backdropEl)) __privateGet(this, _backdropEl).show = false;
      }
    });
  }
  _handleBackdropChange() {
    const parentRoot = this.parentElement?.getRootNode();
    if (!this.backdrop || !parentRoot) return;
    __privateSet(this, _backdropEl, parentRoot.querySelector(this.backdrop));
  }
  _handleMobileLayout(matches) {
    var _a;
    __privateSet(this, _isMobileViewport, matches);
    if (matches && !this.disableMobileStyles) {
      (_a = __privateGet(this, _autoPositionCleanupFn)) == null ? void 0 : _a.call(this);
      this._elDialog?.style.removeProperty("left");
      this._elDialog?.style.removeProperty("top");
      this._elDialog?.style.removeProperty("minWidth");
      this._elDialog?.style.removeProperty("min-width");
    } else {
      this.updateComplete.then(() => {
        __privateMethod(this, _GdsPopover_instances, registerAutoPositioning_fn).call(this);
      });
    }
  }
};
_GdsPopover_instances = new WeakSet();
handleTriggerSlotChange_fn = function() {
  if (this._elTriggerSlot && this._elTriggerSlot.assignedElements()[0]) {
    this._trigger = this._elTriggerSlot.assignedElements()[0];
    this._anchor = this._elTriggerSlot.assignedElements()[0];
  }
};
_autoPositionCleanupFn = new WeakMap();
_isMobileViewport = new WeakMap();
_backdropEl = new WeakMap();
_handleCancel = new WeakMap();
_dispatchUiStateEvent = new WeakMap();
_handleCloseButton = new WeakMap();
registerTriggerEvents_fn = function() {
  this._trigger?.addEventListener("keydown", __privateGet(this, _handleTriggerKeyDown));
  this._trigger?.addEventListener("click", __privateGet(this, _handleTriggerClick));
};
unregisterTriggerEvents_fn = function() {
  var _a;
  this._trigger?.removeEventListener("keydown", __privateGet(this, _handleTriggerKeyDown));
  this._trigger?.removeEventListener("click", __privateGet(this, _handleTriggerClick));
  (_a = __privateGet(this, _autoPositionCleanupFn)) == null ? void 0 : _a.call(this);
};
setupTriggerAttributes_fn = function() {
  if (this._trigger) {
    applyTriggerAriaAttributes(this._trigger, this.open, this.popupRole);
  }
};
registerAutoPositioning_fn = function() {
  if (!this._anchor || !this._elDialog) {
    return;
  }
  const referenceEl = this._anchor;
  const floatingEl = this._elDialog;
  if (!referenceEl || !floatingEl || __privateGet(this, _isMobileViewport) && !this.disableMobileStyles)
    return;
  if (__privateGet(this, _autoPositionCleanupFn)) {
    __privateGet(this, _autoPositionCleanupFn).call(this);
  }
  __privateSet(this, _autoPositionCleanupFn, autoUpdate(referenceEl, floatingEl, () => {
    Object.assign(floatingEl.style, {
      minWidth: this.calcMinWidth(referenceEl),
      maxWidth: this.calcMaxWidth(referenceEl),
      minHeight: this.calcMinHeight(referenceEl),
      maxHeight: this.calcMaxHeight(referenceEl)
    });
    computePosition(referenceEl, floatingEl, {
      placement: this.placement,
      middleware: this.floatingUIMiddleware,
      strategy: "fixed"
    }).then(
      ({ x, y }) => Object.assign(floatingEl.style, {
        left: `${x}px`,
        top: `${y}px`
      })
    );
  }));
};
_handleTriggerKeyDown = new WeakMap();
_handleTriggerClick = new WeakMap();
_focusFirstSlottedChild = new WeakMap();
_handleClickOutside = new WeakMap();
_handlePageScroll = new WeakMap();
GdsPopover.styles = PopoverStyles;
/**
 * The default set of middleware for Floating UI positioning used by GdsPopover.
 */
GdsPopover.DefaultMiddleware = [
  offset(8),
  shift({
    crossAxis: true,
    padding: 8
  })
];
__decorateClass([
  property({ type: Boolean, reflect: true })
], GdsPopover.prototype, "open", 2);
__decorateClass([
  property({ attribute: "popup-role" })
], GdsPopover.prototype, "popupRole", 2);
__decorateClass([
  property({ attribute: false })
], GdsPopover.prototype, "triggerRef", 2);
__decorateClass([
  property({ attribute: false })
], GdsPopover.prototype, "anchorRef", 2);
__decorateClass([
  property()
], GdsPopover.prototype, "label", 2);
__decorateClass([
  property()
], GdsPopover.prototype, "placement", 2);
__decorateClass([
  property({ type: Boolean })
], GdsPopover.prototype, "disableMobileStyles", 2);
__decorateClass([
  property({ type: Boolean })
], GdsPopover.prototype, "disableScrollClose", 2);
__decorateClass([
  property({ type: Boolean })
], GdsPopover.prototype, "autofocus", 2);
__decorateClass([
  property({ attribute: false })
], GdsPopover.prototype, "calcMinWidth", 2);
__decorateClass([
  property({ attribute: false })
], GdsPopover.prototype, "calcMaxWidth", 2);
__decorateClass([
  property({ attribute: false })
], GdsPopover.prototype, "calcMinHeight", 2);
__decorateClass([
  property({ attribute: false })
], GdsPopover.prototype, "calcMaxHeight", 2);
__decorateClass([
  property({ type: Boolean, reflect: true })
], GdsPopover.prototype, "nonmodal", 2);
__decorateClass([
  property()
], GdsPopover.prototype, "backdrop", 2);
__decorateClass([
  property({ attribute: false })
], GdsPopover.prototype, "floatingUIMiddleware", 2);
__decorateClass([
  state()
], GdsPopover.prototype, "_trigger", 2);
__decorateClass([
  state()
], GdsPopover.prototype, "_anchor", 2);
__decorateClass([
  state()
], GdsPopover.prototype, "_isVirtKbVisible", 2);
__decorateClass([
  query("slot:not([name])")
], GdsPopover.prototype, "_elDefaultSlot", 2);
__decorateClass([
  query('slot[name="trigger"]')
], GdsPopover.prototype, "_elTriggerSlot", 2);
__decorateClass([
  query("dialog")
], GdsPopover.prototype, "_elDialog", 2);
__decorateClass([
  watch("triggerRef")
], GdsPopover.prototype, "_handleTriggerRefChanged", 1);
__decorateClass([
  watch("anchorRef")
], GdsPopover.prototype, "_handleAnchorRefChanged", 1);
__decorateClass([
  watch("_trigger")
], GdsPopover.prototype, "_handleTriggerChanged", 1);
__decorateClass([
  watch("_anchor")
], GdsPopover.prototype, "_handleAnchorChanged", 1);
__decorateClass([
  watch("open")
], GdsPopover.prototype, "_handleOpenChange", 1);
__decorateClass([
  watch("backdrop")
], GdsPopover.prototype, "_handleBackdropChange", 1);
__decorateClass([
  watchMediaQuery("(max-width: 576px)")
], GdsPopover.prototype, "_handleMobileLayout", 1);
GdsPopover = __decorateClass([
  gdsCustomElement("gds-popover", { dependsOn: [IconCrossSmall] }),
  localized()
], GdsPopover);
export {
  GdsPopover,
  applyTriggerAriaAttributes
};
