import {
  isReactNode
} from "./chunk-PEK53X7W.js";
import {
  ProgressBar
} from "./chunk-FDIQ522F.js";
import {
  Drawer
} from "./chunk-L6JCKKLU.js";
import {
  useLiveRef
} from "./chunk-UDFJ6IWI.js";
import {
  IconWithCircleBackground
} from "./chunk-L33RQLMZ.js";
import {
  setDefaultReactNodesTypography
} from "./chunk-EZI6E6UO.js";
import {
  toReactNodes
} from "./chunk-OYIPFTQC.js";
import {
  Spacing
} from "./chunk-E5DUKMCU.js";
import {
  overflowAutoWithoutScrollbars
} from "./chunk-FAWI3ZGU.js";
import {
  Button,
  ButtonSelector
} from "./chunk-SIPHI6JZ.js";
import {
  UnstyledButton
} from "./chunk-5NUOBJXP.js";
import {
  z
} from "./chunk-55OQPFLF.js";
import {
  Icon
} from "./chunk-DMPXNHDT.js";
import {
  overlaySurface,
  standardBorderRadius,
  standardContentInset,
  standardFocusOutline
} from "./chunk-HGZGGJQB.js";
import {
  select
} from "./chunk-YMNSXZ5D.js";
import {
  bp,
  useBreakpoints
} from "./chunk-JSGRNWSB.js";
import {
  __objRest,
  __spreadValues
} from "./chunk-W7FAWX6T.js";

// src/components/Modal.tsx
import styled from "@emotion/styled";
import React, {
  Fragment,
  useEffect,
  useLayoutEffect,
  useRef,
  useState
} from "react";
import ReactDOM from "react-dom";
import { Fragment as Fragment2, jsx, jsxs } from "@emotion/react/jsx-runtime";
function isSubmitLinkWithHref(submitLink) {
  return Boolean(submitLink && "href" in submitLink);
}
function Modal({
  visible,
  topContent,
  title,
  description,
  children,
  onClose,
  onCancel,
  cancelDisabled,
  cancelHidden,
  ghost,
  onSubmit,
  submitDisabled,
  submitLoading,
  submitLoadingKind,
  submitText,
  submitIcon,
  submitLink,
  cancelText = "Cancel",
  firstFocusRef,
  smKind = "default",
  top,
  nonDismissable = false,
  autoFocus = true,
  width = 460,
  progressBar,
  buttonOrder,
  buttonLayout = "horizontal",
  extraActions,
  handleBack,
  appendToElement,
  bottomContent,
  topLeftIcon,
  drawerKind,
  drawerPadding,
  drawerCloseButton = true,
  drawerAlignBottom,
  drawerDisableTouchMove,
  voidOverlayBackground
}) {
  const visibleChangedRef = useRef(false);
  const [visibleChanged, setVisibleChanged] = useState(false);
  const nodeRef = useRef(null);
  const [defaultFirstFocusRef, defaultFirstFocusRefCb] = useLiveRef();
  const ref = firstFocusRef || defaultFirstFocusRef;
  const [nodeReady, setNodeReady] = React.useState(false);
  const overlayRef = useRef(null);
  const prevFocusedElement = useRef();
  const modalContainerRef = useRef(null);
  const bp2 = useBreakpoints();
  const isSm = bp2.current("sm" /* sm */);
  useEffect(() => {
    if (visible !== visibleChangedRef.current) {
      visibleChangedRef.current = visible;
      setVisibleChanged(true);
    }
  }, [visible]);
  useEffect(() => {
    if (visibleChanged) {
      setVisibleChanged(false);
    }
  }, [visibleChanged]);
  useEffect(() => {
    prevFocusedElement.current = document.activeElement;
    const elementToAppendTo = appendToElement != null ? appendToElement : document.body;
    if (!nodeRef.current) {
      nodeRef.current = document.createElement("div");
      elementToAppendTo.appendChild(nodeRef.current);
    }
    setNodeReady(true);
    return () => {
      if (nodeRef.current) {
        elementToAppendTo.removeChild(nodeRef.current);
        nodeRef.current = null;
      }
    };
  }, [appendToElement]);
  useEffect(() => {
    const handleOutsideClick = (event) => {
      if (visible && overlayRef.current && event.target && overlayRef.current.contains(event.target) && !nonDismissable) {
        onClose();
      }
    };
    const handleKeyDown = (event) => {
      if (visible && event.key === "Escape" && !nonDismissable) {
        onClose();
      }
    };
    if (visible) {
      if (modalContainerRef.current) {
        modalContainerRef.current.addEventListener("keydown", handleKeyDown);
      }
      if (overlayRef.current) {
        overlayRef.current.addEventListener("click", handleOutsideClick);
      }
    } else {
      if (modalContainerRef.current) {
        modalContainerRef.current.removeEventListener("keydown", handleKeyDown);
      }
      if (overlayRef.current) {
        overlayRef.current.removeEventListener("click", handleOutsideClick);
      }
    }
    const containerRef = modalContainerRef.current;
    const overlayRefVar = overlayRef.current;
    return () => {
      if (containerRef) {
        containerRef.removeEventListener("keydown", handleKeyDown);
      }
      if (overlayRefVar) {
        overlayRefVar.removeEventListener("click", handleOutsideClick);
      }
    };
  }, [onClose, visible, nonDismissable]);
  useLayoutEffect(() => {
    if (visible) {
      if (visibleChanged) {
        prevFocusedElement.current = document.activeElement;
      }
      if (typeof ref === "object" && (ref == null ? void 0 : ref.current) && autoFocus) {
        ref.current.focus();
      }
    } else if (visibleChanged && prevFocusedElement.current) {
      prevFocusedElement.current.focus();
    }
  }, [visible, visibleChanged, ref, autoFocus]);
  function onClickCloseButton(event) {
    event == null ? void 0 : event.stopPropagation();
    onClose();
  }
  function onSubmitForm(e) {
    e.preventDefault();
    e.stopPropagation();
    if (!submitDisabled && onSubmit) {
      onSubmit();
    }
  }
  function onClickCancel() {
    if (onCancel) {
      onCancel();
    } else {
      onClose();
    }
  }
  const linkIsHref = isSubmitLinkWithHref(submitLink);
  const linkIsRoute = !linkIsHref && submitLink;
  const displayCancelAbove = !!buttonOrder ? buttonOrder === "cancel-first" : !isSm;
  const displayCancelBelow = !!buttonOrder ? buttonOrder === "submit-first" : isSm;
  const buttonContent = /* @__PURE__ */ jsxs(Fragment2, { children: [
    extraActions == null ? void 0 : extraActions.filter((action) => action.placement === "above").map((_a, i) => {
      var _b = _a, { placement, text } = _b, rest = __objRest(_b, ["placement", "text"]);
      return /* @__PURE__ */ jsx(Button, __spreadValues({ text }, rest), text || `no-text-${i}`);
    }),
    displayCancelAbove && !cancelHidden && /* @__PURE__ */ jsx(
      Button,
      {
        disabled: cancelDisabled,
        onClick: onClickCancel,
        text: cancelText
      }
    ),
    (onSubmit || submitLink) && /* @__PURE__ */ jsx(
      Button,
      {
        kind: "primary",
        disabled: submitDisabled,
        icon: submitIcon,
        text: submitText != null ? submitText : "Continue",
        loading: submitLoading,
        loadingKind: submitLoadingKind,
        to: linkIsRoute ? submitLink.to : void 0,
        externalLink: linkIsHref ? submitLink.href : void 0,
        filename: linkIsHref ? submitLink.filename : void 0,
        type: submitLink ? "button" : "submit",
        onClick: submitLink ? onSubmit : void 0
      }
    ),
    displayCancelBelow && !cancelHidden && /* @__PURE__ */ jsx(
      Button,
      {
        disabled: cancelDisabled,
        onClick: onClickCancel,
        text: cancelText
      }
    ),
    extraActions == null ? void 0 : extraActions.filter((action) => action.placement === "below").map((_c, i) => {
      var _d = _c, { placement, text } = _d, rest = __objRest(_d, ["placement", "text"]);
      return /* @__PURE__ */ jsx(Button, __spreadValues({ text }, rest), text || `no-text-${i}`);
    })
  ] });
  let titleContent = null;
  if (title) {
    const defaultTypography = {
      type: "Headline",
      heading: "h4",
      size: "Small"
    };
    const titleNodesWithTypography = setDefaultReactNodesTypography(title, {
      default: defaultTypography
    });
    titleContent = /* @__PURE__ */ jsx(ModalTitle, { children: toReactNodes(titleNodesWithTypography) });
  }
  let descriptionContent = null;
  if (description) {
    const defaultTypography = {
      type: "Body",
      size: "ExtraSmall"
    };
    const descriptionNodesWithTypography = setDefaultReactNodesTypography(
      description,
      { default: defaultTypography }
    );
    descriptionContent = /* @__PURE__ */ jsx(ModalDescription, { children: toReactNodes(descriptionNodesWithTypography) });
  }
  let topContentNode = null;
  if (topContent) {
    if (isReactNode(topContent)) {
      topContentNode = topContent;
    } else {
      topContentNode = /* @__PURE__ */ jsx("div", { css: { marginBottom: Spacing.px.xl }, children: /* @__PURE__ */ jsx(IconWithCircleBackground, __spreadValues({}, topContent)) });
    }
  }
  const modalContent = /* @__PURE__ */ jsxs(Fragment, { children: [
    progressBar ? /* @__PURE__ */ jsx("div", { css: { marginBottom: "20px" }, children: /* @__PURE__ */ jsx(
      ProgressBar,
      {
        progressPercentage: progressBar.progressPercentage,
        isSm: progressBar.isSm
      }
    ) }) : null,
    topContentNode,
    titleContent,
    descriptionContent,
    children,
    onSubmit || onCancel || submitLink ? buttonLayout === "horizontal" ? /* @__PURE__ */ jsx(ModalButtonRow, { children: buttonContent }) : /* @__PURE__ */ jsx(ModalButtonColumn, { children: buttonContent }) : null
  ] });
  let content;
  if (smKind === "drawer" && isSm) {
    content = /* @__PURE__ */ jsx(
      Drawer,
      {
        onClose: () => onClickCloseButton(),
        closeButton: drawerCloseButton,
        nonDismissable,
        handleBack,
        kind: drawerKind != null ? drawerKind : "default",
        padding: drawerPadding !== void 0 ? `${drawerPadding}px` : void 0,
        top,
        alignBottom: drawerAlignBottom,
        disableTouchMove: drawerDisableTouchMove != null ? drawerDisableTouchMove : false,
        children: modalContent
      }
    );
  } else {
    content = /* @__PURE__ */ jsxs(Fragment, { children: [
      !(smKind === "fullscreen" && bp2.isSm()) ? /* @__PURE__ */ jsx(
        ModalOverlay,
        {
          ref: overlayRef,
          voidOverlayBackground: voidOverlayBackground != null ? voidOverlayBackground : false
        }
      ) : null,
      /* @__PURE__ */ jsx(
        ModalContainer,
        {
          "aria-modal": true,
          "aria-hidden": true,
          tabIndex: -1,
          onClick: (event) => {
            event.stopPropagation();
          },
          role: "dialog",
          ref: modalContainerRef,
          top: top || (smKind === "default" ? standardContentInset.smPx : 0),
          children: /* @__PURE__ */ jsxs(ModalContent, { width, ghost, smKind, children: [
            !firstFocusRef && /* @__PURE__ */ jsx(DefaultFocusTarget, { ref: defaultFirstFocusRefCb }),
            !ghost && /* @__PURE__ */ jsxs(ModalNavigation, { children: [
              handleBack ? /* @__PURE__ */ jsx(BackButton, { onClick: handleBack, children: /* @__PURE__ */ jsx(Icon, { name: "ChevronLeft", width: 16 }) }) : topLeftIcon ? /* @__PURE__ */ jsx(Icon, __spreadValues({}, topLeftIcon)) : null,
              !nonDismissable && /* @__PURE__ */ jsx(CloseButton, { onClick: onClickCloseButton, type: "button", children: /* @__PURE__ */ jsx(Icon, { name: "Close", width: 9 }) })
            ] }),
            /* @__PURE__ */ jsx(ModalContentInner, { ghost, children: modalContent }),
            bottomContent && /* @__PURE__ */ jsx("div", { css: { marginTop: "auto" }, children: bottomContent })
          ] })
        }
      )
    ] });
  }
  return visible && nodeReady && nodeRef.current ? ReactDOM.createPortal(
    onSubmit ? /* @__PURE__ */ jsx("form", { onSubmit: onSubmitForm, children: content }) : content,
    nodeRef.current
  ) : null;
}
var DefaultFocusTarget = styled(UnstyledButton)`
  position: absolute;
  top: -30px;
  width: 0;
  height: 0;
`;
var ModalOverlay = styled.div`
  position: fixed;
  bottom: 0;
  left: 0;
  z-index: ${z.modalOverlay};
  width: 100vw;
  height: 100vh;
  background: ${({ voidOverlayBackground }) => voidOverlayBackground ? "transparent" : "rgba(0, 0, 0, 0.5)"};
`;
var ModalContainer = styled.div`
  pointer-events: none;
  position: fixed;
  top: 0;
  left: 0;
  z-index: ${z.modalContainer};
  width: 100%;
  height: 100%;
  overflow-x: hidden;
  overflow-y: auto;
  outline: 0;
  display: flex;
  justify-content: center;
  align-items: center;
  color: ${({ theme }) => theme.text};
  ${(props) => `top: ${props.top}px;`}
`;
var contentTopMarginPx = 24;
var ModalDescription = styled.div`
  color: ${({ theme }) => theme.mcNeutral};
  margin-top: ${Spacing.px.sm};
  & + * {
    margin-top: ${contentTopMarginPx}px;
  }
`;
var ModalButtonRow = styled.div`
  margin-top: ${Spacing.px.lg};
  display: flex;
  ${bp.sm(`
    flex-direction: column;
  `)}
  gap: 10px;

  ${ButtonSelector()} {
    width: 50%;
    ${bp.sm(`
      width: 100%;
    `)}
  }
`;
var ModalButtonColumn = styled.div`
  display: flex;
  flex-direction: column;
  gap: ${Spacing.px.sm};

  ${ButtonSelector()} {
    width: 100%;
  }

  margin-top: ${Spacing.px.lg};
`;
var ModalTitle = styled.div`
  margin: 0;
  & + *:not(${select(ModalDescription)}) {
    margin-top: ${contentTopMarginPx}px;
  }
`;
var ModalContent = styled.div`
  pointer-events: auto;
  transition: width 0.25s ease-in;

  ${({ theme, smKind, ghost }) => ghost ? "" : overlaySurface({ theme, border: smKind !== "fullscreen" })}

  ${overflowAutoWithoutScrollbars}
  ${standardContentInset.smCSS.styles}
  max-width: 100%;
  max-height: 100%;
  position: absolute;
  display: flex;
  flex-direction: column;

  ${({ ghost, smKind, width }) => `
    ${ghost ? "" : standardBorderRadius(16)}
    width: ${width}px;
  `}

  ${({ smKind }) => smKind === "fullscreen" ? bp.sm(`
          border-radius: 0px;
          width: 100%;
          height: 100dvh;
        `) : ""}

  ${({ ghost }) => ghost ? "" : "padding: 16px 16px 40px;"}
`;
var ModalNavigation = styled.div`
  display: grid;
  grid-auto-flow: column;
  width: 100%;
`;
var BackButton = styled(UnstyledButton)`
  ${standardFocusOutline}
  width: 24px;
  height: 24px;
  justify-self: flex-start;
`;
var CloseButton = styled(UnstyledButton)`
  ${standardFocusOutline}
  width: 24px;
  height: 24px;
  justify-self: flex-end;
`;
var ModalContentInner = styled.div`
  ${(props) => props.ghost ? "" : "padding: 32px 24px 0;"}
  ${(props) => props.ghost ? "" : `${bp.sm(`
    padding-left: 10px;
    padding-right: 10px;
  `)}`}
`;

export {
  Modal
};
