import { autoUpdate, flip, offset, shift, useFloating } from "@floating-ui/react-dom";
import React, { useContext, useEffect, useState } from "react";
import { RicosContext, ZIndexContext } from "./../../ricos-context/index.js";
import { useDraggableModal } from "./../hooks/use-draggable-modal.js";
import { FocusManager } from "./../../_shared/focus-manager/focus-manager.js";
import { ClickOutside, UiComponentsProvider } from "./../../ui-components/index.js";
const Floating = ({ children, modalConfig, closeModal }) => {
  const { jsdomMode, environment } = useContext(RicosContext);
  const zIndexService = useContext(ZIndexContext);
  const [modalElement, setModalElement] = useState(null);
  const [clampedY, setClampedY] = useState(null);
  const { autoFocus = true, initialFocus, positioning } = modalConfig || {};
  let placement = positioning?.placement;
  const referenceElement = positioning?.referenceElement;
  if (environment === "wixel" && (placement === "right-start" || placement === "bottom")) {
    placement = "bottom-start";
  }
  const middlewares = placement === "right" || placement === "right-start--custom-offset" ? [offset({ mainAxis: 8 })] : placement === "right-start" ? [offset({ mainAxis: 32, crossAxis: -78 })] : placement === "bottom" || placement === "bottom-start" || placement === "bottom-end" ? [offset({ mainAxis: 8 }), flip()] : placement === "left" || placement === "left-start" || placement === "left-end" ? [offset({ mainAxis: 8 }), flip()] : placement === "right-end" ? [offset({ mainAxis: 20 }), flip()] : [];
  const {
    x,
    y,
    isPositioned,
    refs: { setReference, setFloating },
    strategy
  } = useFloating({
    placement: toFloatingPlacement(placement),
    strategy: "fixed",
    middleware: [
      ...middlewares,
      shift({
        crossAxis: true
      })
    ],
    ...modalConfig?.sticky && {
      whileElementsMounted: (referenceEl, floatingEl, update) => {
        return autoUpdate(referenceEl, floatingEl, update, {
          animationFrame: true
        });
      }
    }
  });
  useEffect(() => {
    setReference(referenceElement);
  }, [setReference, referenceElement]);
  const coords = useDraggableModal({
    modalElement,
    dragHandleSelector: modalConfig.enableDrag ? modalConfig.dragHandleSelector : "[data-drag-handle]"
  });
  useEffect(() => {
    setClampedY(null);
  }, [coords]);
  useEffect(() => {
    if (!modalElement) {
      return;
    }
    let prevHeight = modalElement.getBoundingClientRect().height;
    const observer = new ResizeObserver(() => {
      const currentHeight = modalElement.getBoundingClientRect().height;
      const grew = currentHeight > prevHeight;
      prevHeight = currentHeight;
      if (!grew) {
        return;
      }
      const rect = modalElement.getBoundingClientRect();
      const overflow = rect.bottom - window.innerHeight;
      if (overflow > 0) {
        setClampedY(Math.max(0, rect.top - overflow));
      }
    });
    observer.observe(modalElement);
    return () => observer.disconnect();
  }, [modalElement]);
  const isVisible = jsdomMode || isPositioned;
  const content = /* @__PURE__ */ React.createElement(
    "div",
    {
      ref: (ref) => {
        setFloating(ref);
        setModalElement(ref);
      },
      style: {
        top: clampedY ?? coords?.y ?? y ?? "",
        left: coords?.x ?? x ?? "",
        position: strategy,
        zIndex: zIndexService.getZIndex("DIALOG"),
        display: "block",
        visibility: isVisible ? "visible" : "hidden"
      }
    },
    modalElement && /* @__PURE__ */ React.createElement(UiComponentsProvider, { containerEl: modalElement }, children)
  );
  const onClickOutside = (event) => {
    const clickOutsideHandler = typeof modalConfig.onClickOutside === "function" ? modalConfig.onClickOutside : modalConfig.onClickOutside?.handler;
    if (clickOutsideHandler) {
      clickOutsideHandler(event);
    } else if (referenceElement instanceof HTMLElement && !referenceElement?.contains(event.target)) {
      closeModal();
    }
  };
  return /* @__PURE__ */ React.createElement(
    ClickOutside,
    {
      onClickOutside,
      triggerOn: typeof modalConfig.onClickOutside !== "function" ? modalConfig.onClickOutside?.on : void 0
    },
    autoFocus ? /* @__PURE__ */ React.createElement(
      FocusManager,
      {
        focusTrapOptions: {
          returnFocusOnDeactivate: false,
          fallbackFocus: document.activeElement,
          ...initialFocus !== void 0 && { initialFocus }
        },
        jsdomMode,
        active: isVisible,
        preventScroll: true
      },
      content
    ) : content
  );
};
const toFloatingPlacement = (placement) => {
  if (placement === "right-start--custom-offset") {
    return "right-start";
  }
  if (placement === "overlay") {
    return "bottom-start";
  }
  return placement;
};
export {
  Floating
};
//# sourceMappingURL=floating.js.map
