import type React from 'react';
import { useState } from 'react';
import {
	autoPlacement,
	autoUpdate,
	flip,
	offset,
	shift,
	useClick,
	useDismiss,
	useFloating,
	useFloatingNodeId,
	useHover,
	useInteractions,
	useRole,
	type AutoPlacementOptions,
	type ExtendedRefs,
	type FloatingContext,
	type OffsetOptions,
	type Placement,
	type UseClickProps,
	type UseDismissProps,
	type UseHoverProps,
	type UseInteractionsReturn,
	type UseRoleProps,
} from '@floating-ui/react';

export function usePopover(
	props: {
		hover?: boolean | UseHoverProps;
		role?: boolean | UseRoleProps;
		click?: boolean | UseClickProps;
		dismiss?: boolean | UseDismissProps;
		placement?: Placement;
		autoPlacement?: AutoPlacementOptions;
		offset?: OffsetOptions;
		// boundary?: Boundary;
	} = {},
): {
	nodeId: string | undefined;
	refs: ExtendedRefs<any>;
	open: boolean;
	setOpen: (open: boolean) => void;
	floatingStyles: React.CSSProperties;
	context: FloatingContext;
} & UseInteractionsReturn {
	// let { container } = useContainer();
	const [open, setOpen] = useState(false);
	const nodeId = useFloatingNodeId();
	const { refs, floatingStyles, context } = useFloating({
		nodeId,
		placement: props.placement,
		open: open,
		onOpenChange: setOpen,
		middleware: [
			offset(props.offset ?? 10),
			!props.placement &&
				autoPlacement({
					// boundary: props.boundary,
					...props.autoPlacement,
				}),
			// 至少确保在视窗内
			props.placement && flip(),
			shift(),
		],
		whileElementsMounted: autoUpdate,
	});

	const list = [];

	if (props.dismiss ?? true) {
		const dismiss = useDismiss(context, typeof props.dismiss === 'object' ? props.dismiss : {});
		list.push(dismiss);
	}
	if (props.click ?? true) {
		const click = useClick(context, typeof props.click === 'object' ? props.click : {});
		list.push(click);
	}
	if (props.role ?? true) {
		const role = useRole(context, typeof props.role === 'object' ? props.role : {});
		list.push(role);
	}
	if (props.hover) {
		const opts = typeof props.hover === 'object' ? props.hover : { move: false };
		const hover = useHover(context, opts);
		list.push(hover);
	}

	// Merge all the interactions into prop getters
	const { getReferenceProps, getFloatingProps, getItemProps } = useInteractions(list);

	return {
		nodeId,
		refs,
		open,
		setOpen,
		getReferenceProps,
		getFloatingProps,
		getItemProps,
		floatingStyles: floatingStyles as React.CSSProperties,
		context,
	};
}
