"use client";
import { bp, useBreakpoints } from "../styles/breakpoints.js";
import { getColor } from "../styles/themes.js";
import { select } from "../utils/emotion.js";
import { overlaySurface, standardBorderRadius, standardContentInset, standardFocusOutline } from "../styles/common.js";
import { Icon } from "./Icon/Icon.js";
import { overflowAutoWithoutScrollbars } from "../styles/utils.js";
import { toReactNodes } from "../utils/toReactNodes/toReactNodes.js";
import { setDefaultReactNodesTypography } from "../utils/toReactNodes/setReactNodesTypography.js";
import { z } from "../styles/z-index.js";
import { UnstyledButton } from "./UnstyledButton.js";
import { Button, ButtonSelector } from "./Button.js";
import { Spacing } from "../styles/tokens/spacing.js";
import { useLiveRef } from "../hooks/useLiveRef.js";
import { isReactNode } from "../types/typeGuard.js";
import { Drawer } from "./Drawer.js";
import { IconWithCircleBackground } from "./IconWithCircleBackground.js";
import { ProgressBar } from "./ProgressBar.js";
import styled from "@emotion/styled";
import React, { Fragment, useEffect, useLayoutEffect, useRef, useState } from "react";
import { Fragment as Fragment$1, jsx, jsxs } from "@emotion/react/jsx-runtime";
import ReactDOM from "react-dom";
//#region src/components/Modal.tsx
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, overlayBackground }) {
	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 bp = useBreakpoints();
	const isSm = bp.current("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 ?? 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?.current && autoFocus) ref.current.focus();
		} else if (visibleChanged && prevFocusedElement.current) prevFocusedElement.current.focus();
	}, [
		visible,
		visibleChanged,
		ref,
		autoFocus
	]);
	function onClickCloseButton(event) {
		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(Fragment$1, { children: [
		extraActions?.filter((action) => action.placement === "above").map(({ placement, text, ...rest }, i) => /* @__PURE__ */ jsx(Button, {
			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 ?? "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?.filter((action) => action.placement === "below").map(({ placement, text, ...rest }, i) => /* @__PURE__ */ jsx(Button, {
			text,
			...rest
		}, text || `no-text-${i}`))
	] });
	let titleContent = null;
	if (title) titleContent = /* @__PURE__ */ jsx(ModalTitle, { children: toReactNodes(setDefaultReactNodesTypography(title, { default: {
		type: "Headline",
		heading: "h4",
		size: "Small"
	} })) });
	let descriptionContent = null;
	if (description) descriptionContent = /* @__PURE__ */ jsx(ModalDescription, { children: toReactNodes(setDefaultReactNodesTypography(description, { default: {
		type: "Body",
		size: "ExtraSmall"
	} })) });
	let topContentNode = null;
	if (topContent) if (isReactNode(topContent)) topContentNode = topContent;
	else topContentNode = /* @__PURE__ */ jsx("div", {
		css: { marginBottom: Spacing.px.xl },
		children: /* @__PURE__ */ jsx(IconWithCircleBackground, { ...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 ?? "default",
		padding: drawerPadding !== void 0 ? `${drawerPadding}px` : void 0,
		alignBottom: drawerAlignBottom,
		disableTouchMove: drawerDisableTouchMove ?? false,
		top,
		children: modalContent
	});
	else content = /* @__PURE__ */ jsxs(Fragment, { children: [!(smKind === "fullscreen" && bp.isSm()) ? /* @__PURE__ */ jsx(ModalOverlay, {
		ref: overlayRef,
		overlayBackground
	}) : 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, { ...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;
}
const DefaultFocusTarget = styled(UnstyledButton)`
  position: absolute;
  top: -30px;
  width: 0;
  height: 0;
`;
const ModalOverlay = styled.div`
  position: fixed;
  bottom: 0;
  left: 0;
  z-index: ${z.modalOverlay};
  width: 100vw;
  height: 100dvh;
  background: ${({ overlayBackground, theme }) => overlayBackground ? getColor(theme, overlayBackground) : "rgba(0, 0, 0, 0.5)"};
`;
const 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;`}
`;
const contentTopMarginPx = 24;
const ModalDescription = styled.div`
  color: ${({ theme }) => theme.mcNeutral};
  margin-top: ${Spacing.px.sm};
  & + * {
    margin-top: ${contentTopMarginPx}px;
  }
`;
const ModalButtonRow = styled.div`
  margin-top: ${Spacing.px.lg};
  display: flex;
  ${bp.sm(`
    flex-direction: column;
  `)}
  gap: 10px;

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

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

  margin-top: ${Spacing.px.lg};
`;
const ModalTitle = styled.div`
  margin: 0;
  & + *:not(${select(ModalDescription)}) {
    margin-top: ${contentTopMarginPx}px;
  }
`;
const 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;"}
`;
const ModalNavigation = styled.div`
  display: grid;
  grid-auto-flow: column;
  width: 100%;
`;
const BackButton = styled(UnstyledButton)`
  ${standardFocusOutline}
  width: 24px;
  height: 24px;
  justify-self: flex-start;
`;
const CloseButton = styled(UnstyledButton)`
  ${standardFocusOutline}
  width: 24px;
  height: 24px;
  justify-self: flex-end;
`;
const ModalContentInner = styled.div`
  ${(props) => props.ghost ? "" : "padding: 32px 24px 0;"}
  ${(props) => props.ghost ? "" : `${bp.sm(`
    padding-left: 10px;
    padding-right: 10px;
  `)}`}
`;
//#endregion
export { Modal };
