import { bp } from "../styles/breakpoints.js";
import { themeOr } from "../styles/themes.js";
import { Link } from "../router.js";
import { overlaySurface, standardBorderRadius, standardFocusOutline } from "../styles/common.js";
import { Icon } from "./Icon/Icon.js";
import { toReactNodes } from "../utils/toReactNodes/toReactNodes.js";
import { z } from "../styles/z-index.js";
import { UnstyledButton } from "./UnstyledButton.js";
import { Button } from "./Button.js";
import { Toggle } from "./Toggle.js";
import { useLiveRef } from "../hooks/useLiveRef.js";
import { smHeaderLogoMarginLeft } from "../styles/constants.js";
import { Flex } from "./Flex.js";
import { MultiToggle } from "./MultiToggle.js";
import styled from "@emotion/styled";
import { useCallback, useEffect, useLayoutEffect, useRef, useState } from "react";
import { css, useTheme } from "@emotion/react";
import { Fragment as Fragment$1, jsx, jsxs } from "@emotion/react/jsx-runtime";
import ReactDOM from "react-dom";
//#region src/components/Dropdown.tsx
function Dropdown({ button, dropdownItems, horizontalScrollRef, onClickDropdownItems, getCSS, getDropdownItemsCSS, isOpen: isOpenProp, onOpen, onClose, closeOnScroll = false, openOnHover = false, minDropdownItemsWidth = 200, maxDropdownItemsWidth = 300, align = "center", dropdownItemOffsetTop: dropdownItemOffsetTopProp = 0, verticalPlacement = "bottom", footer = null, getFooterCSS, dropdownContent = null, borderRadius = 8 }) {
	const theme = useTheme();
	const [isOpen, setIsOpen] = useState(isOpenProp || false);
	const [dropdownButtonHeight, setDropdownButtonHeight] = useState(0);
	const [dropdownButtonWidth, setDropdownButtonWidth] = useState(0);
	const [dropdownCoords, setDropdownCoords] = useState({
		top: 0,
		left: 0,
		right: 0
	});
	const dropdownRef = useRef(null);
	const [dropdownButtonRef, dropdownButtonRefCb] = useLiveRef();
	const dropdownItemsRef = useRef(null);
	const [dropdownItemsWidth, setDropdownItemsWidth] = useState(0);
	const [dropdownItemsHeight, setDropdownItemsHeight] = useState(0);
	const nodeRef = useRef(null);
	const [nodeReady, setNodeReady] = useState(false);
	useEffect(() => {
		if (isOpenProp !== void 0) setIsOpen(isOpenProp);
	}, [isOpenProp]);
	useEffect(() => {
		if (!nodeRef.current) {
			nodeRef.current = document.createElement("div");
			document.body.appendChild(nodeRef.current);
		}
		setNodeReady(true);
		return () => {
			if (nodeRef.current) {
				document.body.removeChild(nodeRef.current);
				nodeRef.current = null;
			}
		};
	}, []);
	const setOpen = useCallback((newValue) => {
		setIsOpen(newValue);
		if (newValue && onOpen) onOpen();
		else if (!newValue && onClose) onClose();
	}, [onOpen, onClose]);
	function handleKeyDown(event) {
		if (event.key === "Escape") {
			event.preventDefault();
			setOpen(false);
		} else if (["Enter", "Return"].includes(event.key)) {
			event.preventDefault();
			setOpen(!isOpen);
		}
	}
	function handleBlur(event) {
		if (dropdownItemsRef.current && !dropdownItemsRef.current.contains(event.relatedTarget) && event.relatedTarget !== null) setOpen(false);
	}
	useEffect(() => {
		function handleClickOutside(event) {
			const targetOutsideDropdownItems = dropdownItemsRef.current && !dropdownItemsRef.current.contains(event.target);
			const targetOutsideDropdownButton = dropdownButtonRef.current && !dropdownButtonRef.current.contains(event.target);
			if (isOpen && event.target && targetOutsideDropdownItems && targetOutsideDropdownButton) setOpen(false);
		}
		window.document.addEventListener("mousedown", handleClickOutside);
		return () => {
			window.document.removeEventListener("mousedown", handleClickOutside);
		};
	}, [
		isOpen,
		setOpen,
		dropdownButtonRef
	]);
	const reposition = useCallback(() => {
		if (dropdownButtonRef.current && dropdownItemsRef.current) {
			const dropdownButtonRect = dropdownButtonRef.current.getBoundingClientRect();
			setDropdownCoords({
				top: dropdownButtonRect.top,
				left: dropdownButtonRect.left,
				right: dropdownButtonRect.right
			});
			setDropdownButtonHeight(dropdownButtonRect.height);
			setDropdownButtonWidth(dropdownButtonRect.width);
			const dropdownItemsRect = dropdownItemsRef.current.getBoundingClientRect();
			setDropdownItemsWidth(dropdownItemsRect.width);
			setDropdownItemsHeight(dropdownItemsRect.height);
		}
	}, [dropdownButtonRef]);
	useLayoutEffect(() => {
		function onWindowResize() {
			setOpen(false);
			reposition();
		}
		function handleScroll() {
			if (closeOnScroll) setOpen(false);
			reposition();
		}
		reposition();
		let dropdownButtonResizeObserver = null;
		if (dropdownButtonRef.current) {
			dropdownButtonResizeObserver = new ResizeObserver(reposition);
			dropdownButtonResizeObserver.observe(dropdownButtonRef.current);
		}
		let dropdownResizeObserver = null;
		if (dropdownButtonRef.current) {
			dropdownResizeObserver = new ResizeObserver(reposition);
			dropdownResizeObserver.observe(dropdownButtonRef.current);
		}
		window.addEventListener("resize", onWindowResize);
		let navItemsResizeObserver = null;
		window.addEventListener("scroll", handleScroll);
		if (horizontalScrollRef?.current) {
			horizontalScrollRef.current.addEventListener("scroll", handleScroll);
			navItemsResizeObserver = new ResizeObserver(reposition);
			navItemsResizeObserver.observe(horizontalScrollRef.current);
		}
		return () => {
			window.removeEventListener("resize", onWindowResize);
			window.removeEventListener("scroll", handleScroll);
			dropdownButtonResizeObserver?.disconnect();
			navItemsResizeObserver?.disconnect();
			dropdownResizeObserver?.disconnect();
		};
	}, [
		setOpen,
		horizontalScrollRef,
		closeOnScroll,
		reposition,
		dropdownButtonRef
	]);
	const handleClickDropdownItems = useCallback(() => {
		setOpen(false);
		onClickDropdownItems && onClickDropdownItems();
	}, [onClickDropdownItems, setOpen]);
	const dropdownTopMargin = 8;
	let dropdownItemOffsetTop = dropdownCoords.top + dropdownButtonHeight + dropdownTopMargin + dropdownItemOffsetTopProp;
	let dropdownItemOffsetLeft = dropdownCoords.left;
	if (align === "center") dropdownItemOffsetLeft = dropdownCoords.left - (dropdownItemsWidth - dropdownButtonWidth) / 2;
	else if (align === "right") dropdownItemOffsetLeft = dropdownCoords.right - dropdownItemsWidth;
	if (verticalPlacement === "top") dropdownItemOffsetTop = dropdownCoords.top - dropdownItemsHeight - dropdownTopMargin;
	const commonButtonProps = {
		id: button.id,
		type: "button",
		onMouseEnter: () => {
			if (openOnHover) {
				reposition();
				setOpen(true);
			}
		},
		onMouseLeave: () => {
			if (openOnHover) setOpen(false);
		},
		onMouseDown: () => {
			reposition();
			setOpen(!isOpen);
		},
		onKeyDown: handleKeyDown,
		onFocus: () => {
			reposition();
			setOpen(true);
		},
		onBlur: handleBlur,
		ref: dropdownButtonRefCb
	};
	const commonUnstyledButtonProps = {
		...commonButtonProps,
		css: "getCSS" in button && button.getCSS ? button.getCSS({
			isOpen,
			theme
		}) : void 0
	};
	let buttonNode = null;
	if ("label" in button) buttonNode = /* @__PURE__ */ jsx(UnstyledDropdownButton, {
		...commonUnstyledButtonProps,
		children: button.label
	});
	else if ("getContent" in button) buttonNode = /* @__PURE__ */ jsx(UnstyledDropdownButton, {
		...commonUnstyledButtonProps,
		children: button.getContent({
			isOpen,
			theme
		})
	});
	else buttonNode = /* @__PURE__ */ jsx(Button, {
		...button,
		...commonButtonProps
	});
	const containerCSS = getCSS && getCSS({
		isOpen,
		theme
	});
	const dropdownItemsCSS = getDropdownItemsCSS && getDropdownItemsCSS({
		isOpen,
		theme
	});
	const footerCSS = getFooterCSS && getFooterCSS({
		isOpen,
		theme
	});
	return /* @__PURE__ */ jsxs("div", {
		css: {
			position: "relative",
			display: "inline-flex",
			...containerCSS
		},
		ref: dropdownRef,
		children: [buttonNode, nodeReady && nodeRef.current ? ReactDOM.createPortal(/* @__PURE__ */ jsxs(DropdownItems, {
			isOpen,
			left: dropdownItemOffsetLeft,
			top: dropdownItemOffsetTop,
			ref: dropdownItemsRef,
			minWidth: minDropdownItemsWidth,
			maxWidth: maxDropdownItemsWidth,
			hasItems: dropdownItems ? dropdownItems.length > 0 : false,
			borderRadius,
			css: dropdownItemsCSS,
			children: [
				dropdownItems?.map((dropdownItem, i) => {
					return /* @__PURE__ */ jsx("li", {
						onBlur: handleBlur,
						children: /* @__PURE__ */ jsx(DropdownItem, {
							dropdownItem,
							dropdownButtonHeight,
							onClick: handleClickDropdownItems,
							getDropdownCss: getCSS
						})
					}, `${dropdownItem.to ?? ""}${dropdownItem.hash ? `#${dropdownItem.hash}` : ""}-${i}`);
				}),
				dropdownContent,
				footer && /* @__PURE__ */ jsx(DropdownFooter, {
					...footerCSS && { css: footerCSS },
					children: footer
				})
			]
		}), nodeRef.current) : null]
	});
}
const DropdownFooter = styled.div`
  ${({ css, theme }) => css ? css : `
    padding: 24px 16px 0;
    border-top: 1px solid ${theme.c2Neutral};
    margin-top: 16px;
  `}
`;
const DropdownItems = styled.ul`
  ${overlaySurface}
  color: ${({ theme }) => themeOr(theme.c6Neutral, theme.c8Neutral)};
  ${({ borderRadius }) => standardBorderRadius(borderRadius)}
  ${({ hasItems }) => hasItems ? "padding: 12px 0;" : "padding: 0;"}
  visibility: ${({ isOpen }) => isOpen ? "visible" : "hidden"};
  position: fixed;
  ${({ minWidth }) => minWidth ? `min-width: ${minWidth}px;` : ""}
  ${({ maxWidth }) => maxWidth ? `max-width: ${maxWidth}px;` : ""}
  left: ${({ left }) => left}px;
  top: ${({ top }) => top}px;
  z-index: ${z.dropdown};
  list-style: none;
  margin: 0;
`;
function DropdownItem({ dropdownItem, dropdownButtonHeight, onClick, getDropdownCss }) {
	const theme = useTheme();
	const [showSubDropdown, setShowSubDropdown] = useState(false);
	const iconSide = dropdownItem.iconSide || "left";
	const dropdownItemIcon = dropdownItem.getIcon && dropdownItem.getIcon({
		dropdownItem,
		theme
	});
	const dropdownItemIconNode = dropdownItemIcon ? /* @__PURE__ */ jsx(Icon, {
		name: dropdownItemIcon.name,
		width: dropdownItemIcon.width || 12,
		mr: iconSide === "left" ? 10 : 0
	}) : null;
	const cssProp = dropdownItem.getCSS && dropdownItem.getCSS({
		theme,
		dropdownItem
	});
	const onClickDropdownItem = useCallback(() => {
		dropdownItem.onClick && dropdownItem.onClick(dropdownItem);
		onClick && onClick();
	}, [dropdownItem, onClick]);
	const onMouseEnter = useCallback(() => {
		dropdownItem.subDropdown && setShowSubDropdown(true);
	}, [dropdownItem]);
	const onMouseLeave = useCallback(() => {
		dropdownItem.subDropdown && setShowSubDropdown(false);
	}, [dropdownItem]);
	const iconAndLabel = /* @__PURE__ */ jsxs(Fragment$1, { children: [iconSide === "left" && /* @__PURE__ */ jsxs(Fragment$1, { children: [dropdownItemIconNode, toReactNodes(dropdownItem.label)] }), iconSide === "right" && /* @__PURE__ */ jsxs(Flex, {
		justify: "space-between",
		align: "center",
		width: "100%",
		children: [toReactNodes(dropdownItem.label), dropdownItemIconNode]
	})] });
	if (dropdownItem.to !== void 0 || dropdownItem.externalLink) return /* @__PURE__ */ jsx(DropdownItemLink, {
		selected: Boolean(dropdownItem.selected),
		to: dropdownItem.to,
		externalLink: dropdownItem.externalLink,
		params: dropdownItem.params,
		onClick: onClickDropdownItem,
		css: cssProp,
		hash: dropdownItem.hash,
		children: iconAndLabel
	});
	if (dropdownItem.toggle) return /* @__PURE__ */ jsxs(DropdownItemDiv, {
		selected: false,
		css: cssProp,
		withHoverColor: false,
		children: [iconAndLabel, /* @__PURE__ */ jsx("div", {
			css: { marginLeft: "auto" },
			children: "options" in dropdownItem.toggle ? /* @__PURE__ */ jsx(MultiToggle, { ...dropdownItem.toggle }) : /* @__PURE__ */ jsx(Toggle, { ...dropdownItem.toggle })
		})]
	});
	if (dropdownItem.subDropdown) return /* @__PURE__ */ jsxs(DropdownItemDiv, {
		selected: false,
		css: cssProp,
		onMouseEnter,
		onMouseLeave,
		children: [iconAndLabel, /* @__PURE__ */ jsx(dropdownItem.subDropdown.customDropdown || Dropdown, {
			button: {
				label: "",
				getCSS: getDropdownCss
			},
			dropdownItems: dropdownItem.subDropdown.subItems,
			align: "left",
			dropdownItemOffsetTop: -dropdownButtonHeight,
			isOpen: showSubDropdown,
			onOpen: () => setShowSubDropdown(true),
			onClose: () => setShowSubDropdown(false)
		})]
	});
	return /* @__PURE__ */ jsx(DropdownItemDiv, {
		selected: false,
		css: cssProp,
		onClick: onClickDropdownItem,
		children: iconAndLabel
	});
}
const UnstyledDropdownButton = styled(UnstyledButton)`
  ${standardFocusOutline}
`;
const dropdownItemStyle = ({ theme, selected, withHoverColor = true }) => `
  background-color: ${selected ? theme.primary : "transparent"};
  box-sizing: border-box;
  cursor: pointer;
  display: flex;
  flex-direction: row;
  align-items: center;
  height: 100%;
  outline-color: ${selected ? theme.onPrimaryText : theme.hcNeutral} !important;
  white-space: nowrap;

  padding: 8px 16px;
  ${bp.sm(`padding-left: ${smHeaderLogoMarginLeft};`)}

  ${withHoverColor ? `
      &:hover {
        color: ${theme.hcNeutral} !important;
      }
      ` : ""}
`;
const cssProp = ({ theme, selected }) => css`
  ${dropdownItemStyle({
	theme,
	selected: Boolean(selected)
})}
  ${standardFocusOutline({ theme })}
`;
function DropdownItemLink(props) {
	const theme = useTheme();
	return /* @__PURE__ */ jsx(Link, {
		...props,
		css: cssProp({
			theme,
			selected: Boolean(props.selected)
		})
	});
}
const DropdownItemDiv = styled.div`
  ${dropdownItemStyle}
  ${standardFocusOutline}
`;
//#endregion
export { Dropdown };
