"use client";
import { useCallback, useEffect, useRef, useState } from "react";
import { useDidUpdate, useIsomorphicEffect, useUncontrolled } from "@mantine/hooks";
import { arrow, autoUpdate, flip, hide, inline, limitShift, offset, shift, size, useFloating } from "@floating-ui/react";
//#region packages/@mantine/core/src/components/Popover/use-popover.ts
function getDefaultMiddlewares(middlewares) {
	if (middlewares === void 0) return {
		shift: true,
		flip: true
	};
	const result = { ...middlewares };
	if (middlewares.shift === void 0) result.shift = true;
	if (middlewares.flip === void 0) result.flip = true;
	return result;
}
function getPopoverMiddlewares(options, getFloating, disableFlip, lockEnabled) {
	const middlewaresOptions = getDefaultMiddlewares(options.middlewares);
	const middlewares = [offset(options.offset), hide()];
	if (middlewaresOptions.flip && !disableFlip) {
		const userFlip = typeof middlewaresOptions.flip === "boolean" ? {} : middlewaresOptions.flip;
		const flipOptions = lockEnabled ? {
			fallbackStrategy: "initialPlacement",
			...userFlip
		} : userFlip;
		middlewares.push(flip(flipOptions));
	}
	if (middlewaresOptions.shift) middlewares.push(shift(typeof middlewaresOptions.shift === "boolean" ? {
		limiter: limitShift(),
		padding: 5
	} : {
		limiter: limitShift(),
		padding: 5,
		...middlewaresOptions.shift
	}));
	if (middlewaresOptions.inline) middlewares.push(typeof middlewaresOptions.inline === "boolean" ? inline() : inline(middlewaresOptions.inline));
	middlewares.push(arrow({
		element: options.arrowRef,
		padding: options.arrowOffset
	}));
	if (middlewaresOptions.size || options.width === "target") middlewares.push(size({
		...typeof middlewaresOptions.size === "boolean" ? {} : middlewaresOptions.size,
		apply({ rects, availableWidth, availableHeight, ...rest }) {
			const styles = getFloating().refs.floating.current?.style ?? {};
			if (middlewaresOptions.size) if (typeof middlewaresOptions.size === "object" && !!middlewaresOptions.size.apply) middlewaresOptions.size.apply({
				rects,
				availableWidth,
				availableHeight,
				...rest
			});
			else Object.assign(styles, {
				maxWidth: `${availableWidth}px`,
				maxHeight: `${availableHeight}px`
			});
			if (options.width === "target") Object.assign(styles, { width: `${rects.reference.width}px` });
		}
	}));
	return middlewares;
}
function usePopover(options) {
	const [_opened, setOpened] = useUncontrolled({
		value: options.opened,
		defaultValue: options.defaultOpened,
		finalValue: false,
		onChange: options.onChange
	});
	const previouslyOpened = useRef(_opened);
	const [lockedPlacement, setLockedPlacement] = useState(null);
	const lockEnabled = options.preventPositionChangeWhenVisible !== false;
	const wasOpenedRef = useRef(_opened);
	if (_opened !== wasOpenedRef.current) {
		wasOpenedRef.current = _opened;
		if (_opened && lockedPlacement !== null) setLockedPlacement(null);
	}
	const resetLockedPlacement = useCallback(() => setLockedPlacement(null), []);
	const onClose = () => {
		if (_opened && !options.disabled) setOpened(false);
	};
	const onToggle = () => {
		if (!options.disabled) setOpened(!_opened);
	};
	const floating = useFloating({
		open: _opened,
		strategy: options.strategy,
		placement: lockEnabled ? lockedPlacement ?? options.position : options.position,
		middleware: getPopoverMiddlewares(options, () => floating, lockEnabled && lockedPlacement !== null, lockEnabled),
		whileElementsMounted: !options.keepMounted ? autoUpdate : void 0
	});
	useEffect(() => {
		if (!floating.refs.reference.current || !floating.refs.floating.current) return;
		if (_opened) return autoUpdate(floating.refs.reference.current, floating.refs.floating.current, floating.update);
	}, [_opened, floating.update]);
	const measuredAfterShowRef = useRef(false);
	useIsomorphicEffect(() => {
		if (!_opened) {
			measuredAfterShowRef.current = false;
			return;
		}
		if (!lockEnabled || lockedPlacement !== null) return;
		const flEl = floating.refs.floating.current;
		if (!flEl || flEl.offsetHeight === 0 || flEl.offsetWidth === 0) return;
		if (!measuredAfterShowRef.current) {
			measuredAfterShowRef.current = true;
			floating.update();
			return;
		}
		if (floating.isPositioned) setLockedPlacement(floating.placement);
	}, [
		lockEnabled,
		_opened,
		floating.isPositioned,
		floating.placement,
		lockedPlacement,
		floating.update
	]);
	const previousPlacementRef = useRef(floating.placement);
	useIsomorphicEffect(() => {
		if (previousPlacementRef.current !== floating.placement) {
			previousPlacementRef.current = floating.placement;
			options.onPositionChange?.(floating.placement);
		}
	}, [floating.placement]);
	useDidUpdate(() => {
		if (_opened !== previouslyOpened.current) if (!_opened) options.onClose?.();
		else options.onOpen?.();
		previouslyOpened.current = _opened;
	}, [
		_opened,
		options.onClose,
		options.onOpen
	]);
	return {
		floating,
		controlled: typeof options.opened === "boolean",
		opened: _opened,
		onClose,
		onToggle,
		resetLockedPlacement
	};
}
//#endregion
export { usePopover };

//# sourceMappingURL=use-popover.mjs.map