/* COPYRIGHT Esri - https://js.arcgis.com/5.1/LICENSE.txt */
import { c as customElement } from "../../chunks/runtime.js";
import { css, html } from "lit";
import { LitElement, safeClassMap } from "@arcgis/lumina";
import { createRef, ref } from "lit/directives/ref.js";
import { c as createObserver } from "../../chunks/observers.js";
import { w as whenAnimationDone } from "../../chunks/dom.js";
import { u as useSetFocus } from "../../chunks/useSetFocus.js";
const CSS = {
  frame: "frame",
  frameAdvancing: "frame--advancing",
  frameRetreating: "frame--retreating"
};
const styles = css`:host{box-sizing:border-box;background-color:var(--calcite-color-foreground-1);color:var(--calcite-color-text-2);font-size:var(--calcite-font-size--1)}:host *{box-sizing:border-box}:host{position:relative;display:flex;inline-size:100%;flex:1 1 auto;align-items:stretch;overflow:hidden;background-color:transparent}:host .frame{position:relative;margin:0;display:flex;inline-size:100%;flex:1 1 auto;flex-direction:column;align-items:stretch;padding:0;animation-name:none;animation-duration:var(--calcite-animation-timing);background-color:var(--calcite-flow-background-color)}:host ::slotted(*){display:none;block-size:100%}:host ::slotted(*[selected]){display:flex}:host .frame--advancing{animation-name:calcite-frame-advance}:host .frame--retreating{animation-name:calcite-frame-retreat}@keyframes calcite-frame-advance{0%{--tw-bg-opacity: .5;transform:translate3d(50px,0,0)}to{--tw-bg-opacity: 1;transform:translateZ(0)}}@keyframes calcite-frame-retreat{0%{--tw-bg-opacity: .5;transform:translate3d(-50px,0,0)}to{--tw-bg-opacity: 1;transform:translateZ(0)}}:host([hidden]){display:none}[hidden]{display:none}`;
class Flow extends LitElement {
  constructor() {
    super();
    this.frameRef = createRef();
    this.itemMutationObserver = createObserver("mutation", () => this.updateItemsAndProps());
    this.items = [];
    this.selectedIndex = -1;
    this.focusSetter = useSetFocus()(this);
    this.flowDirection = "standby";
    this.listen("calciteInternalFlowItemChange", this.handleCalciteInternalFlowItemChange);
    this.listen("calciteFlowItemBack", this.handleItemBackClick);
  }
  static {
    this.properties = { flowDirection: [16, {}, { state: true }], customItemSelectors: 1 };
  }
  static {
    this.styles = styles;
  }
  async back() {
    const { items, selectedIndex } = this;
    const selectedItem = items[selectedIndex];
    const nextSelectedItem = items[selectedIndex - 1];
    if (!selectedItem || !nextSelectedItem) {
      return;
    }
    const beforeBack = selectedItem.beforeBack ? selectedItem.beforeBack : () => Promise.resolve();
    try {
      await beforeBack.call(selectedItem);
    } catch {
      return;
    }
    selectedItem.selected = false;
    nextSelectedItem.selected = true;
    return nextSelectedItem;
  }
  async setFocus(options) {
    return this.focusSetter(() => this.items[this.selectedIndex], options);
  }
  connectedCallback() {
    super.connectedCallback();
    this.itemMutationObserver?.observe(this.el, { childList: true, subtree: true });
  }
  willUpdate(changes) {
    if (changes.has("flowDirection") && (this.hasUpdated || this.flowDirection !== "standby")) {
      this.handleFlowDirectionChange(this.flowDirection);
    }
  }
  loaded() {
    this.updateItemsAndProps();
  }
  disconnectedCallback() {
    super.disconnectedCallback();
    this.itemMutationObserver?.disconnect();
  }
  async handleFlowDirectionChange(flowDirection) {
    if (flowDirection === "standby" || !this.frameRef.value) {
      return;
    }
    await whenAnimationDone(this.frameRef.value, flowDirection === "retreating" ? "calcite-frame-retreat" : "calcite-frame-advance");
    this.resetFlowDirection();
  }
  handleCalciteInternalFlowItemChange(event) {
    event.stopPropagation();
    this.updateFlowProps();
  }
  async handleItemBackClick(event) {
    if (event.defaultPrevented) {
      return;
    }
    await this.back();
    return this.setFocus();
  }
  resetFlowDirection() {
    this.flowDirection = "standby";
  }
  getFlowDirection(oldSelectedIndex, newSelectedIndex) {
    const allowRetreatingDirection = oldSelectedIndex > 0;
    const allowAdvancingDirection = oldSelectedIndex > -1 && newSelectedIndex > 0;
    if (!allowAdvancingDirection && !allowRetreatingDirection) {
      return "standby";
    }
    return newSelectedIndex < oldSelectedIndex ? "retreating" : "advancing";
  }
  updateItemsAndProps() {
    const { customItemSelectors, el } = this;
    const newItems = Array.from(el.querySelectorAll(`calcite-flow-item${customItemSelectors ? `,${customItemSelectors}` : ""}`)).filter((flowItem) => flowItem.closest("calcite-flow") === el);
    this.items = newItems;
    this.ensureSelectedFlowItemExists();
    this.updateFlowProps();
  }
  updateFlowProps() {
    const { selectedIndex, items } = this;
    const foundSelectedIndex = this.findSelectedFlowItemIndex(items);
    items.forEach((flowItem, index) => {
      const currentlySelected = index === foundSelectedIndex;
      if (!currentlySelected) {
        flowItem.menuOpen = false;
      }
      flowItem.showBackButton = currentlySelected && foundSelectedIndex > 0;
    });
    if (foundSelectedIndex === -1) {
      return;
    }
    if (selectedIndex !== foundSelectedIndex) {
      this.flowDirection = this.getFlowDirection(selectedIndex, foundSelectedIndex);
    }
    this.selectedIndex = foundSelectedIndex;
  }
  findSelectedFlowItemIndex(items) {
    const selectedItem = items.slice(0).reverse().find((item) => !!item.selected);
    return selectedItem ? items.indexOf(selectedItem) : -1;
  }
  ensureSelectedFlowItemExists() {
    const { items } = this;
    const foundSelectedIndex = this.findSelectedFlowItemIndex(items);
    if (foundSelectedIndex !== -1) {
      return;
    }
    const lastItem = items[items.length - 1];
    if (lastItem) {
      lastItem.selected = true;
    }
  }
  render() {
    const { flowDirection } = this;
    const frameDirectionClasses = {
      [CSS.frame]: true,
      [CSS.frameAdvancing]: flowDirection === "advancing",
      [CSS.frameRetreating]: flowDirection === "retreating"
    };
    return html`<div class=${safeClassMap(frameDirectionClasses)} ${ref(this.frameRef)}><slot></slot></div>`;
  }
}
customElement("calcite-flow", Flow);
export {
  Flow
};
