import { extractButtonLabel } from "../utils/extractText.js";
import { cloneElement, isValidElement, useCallback, useEffect, useMemo, useRef, useState } from "react";
//#region src/components/PisellProcedure/hooks/useOverflowActions.ts
/**
* 检查元素是否是按钮（根据类名是否包含 "btn"）
*/
const isButtonElement = (element) => {
	const className = (element.props || {}).className;
	if (typeof className === "string" && className.includes("btn")) return true;
	if (Array.isArray(className)) return className.some((cls) => typeof cls === "string" && cls.includes("btn"));
	return false;
};
/**
* 递归提取所有按钮元素
*/
const extractButtons = (node, index = 0) => {
	const buttons = [];
	if (!node) return buttons;
	if (Array.isArray(node)) {
		node.forEach((item, i) => {
			buttons.push(...extractButtons(item, i));
		});
		return buttons;
	}
	if (isValidElement(node)) {
		const element = node;
		if (isButtonElement(element)) {
			var _element$key;
			buttons.push(cloneElement(element, { key: (_element$key = element.key) !== null && _element$key !== void 0 ? _element$key : `btn-${index}` }));
			return buttons;
		}
		if (element.props && element.props.children) {
			const childButtons = extractButtons(element.props.children, index);
			buttons.push(...childButtons);
		}
	}
	return buttons;
};
/**
* 溢出收纳 Hook
* @description 处理操作按钮的溢出收纳逻辑，支持左侧自定义内容
*/
const useOverflowActions = (options) => {
	const { children, gap = 16 } = options;
	const containerRef = useRef(null);
	const measureRef = useRef(null);
	const moreButtonRef = useRef(null);
	const leftSlotRef = useRef(null);
	const [itemWidths, setItemWidths] = useState([]);
	const [moreButtonWidth, setMoreButtonWidth] = useState(80);
	const [availableWidth, setAvailableWidth] = useState(0);
	/**
	* 找到所有按钮元素
	*/
	const actionItems = useMemo(() => {
		return extractButtons(children);
	}, [children]);
	/**
	* 测量所有按钮的宽度
	*/
	const measureWidths = useCallback(() => {
		if (typeof window === "undefined" || !measureRef.current || !moreButtonRef.current) return;
		try {
			const buttons = measureRef.current.querySelectorAll("[data-measure-item]");
			const widths = [];
			buttons.forEach((btn) => {
				const rect = btn.getBoundingClientRect();
				if (rect) widths.push(Math.ceil(rect.width));
			});
			setItemWidths(widths);
			const moreBtnRect = moreButtonRef.current.getBoundingClientRect();
			if (moreBtnRect) setMoreButtonWidth(Math.ceil(moreBtnRect.width));
		} catch (error) {
			console.warn("Failed to measure button widths:", error);
		}
	}, []);
	/**
	* 更新可用宽度
	* 计算逻辑：容器宽度 - 左侧插槽宽度 - 间距
	* 
	* 注意：统一使用 getBoundingClientRect() 来获取宽度，
	* 因为 offsetWidth 返回 CSS 像素不受缩放影响，
	* 而 getBoundingClientRect() 返回视觉像素（受缩放影响）。
	* 混用会导致在页面缩放时计算错误。
	*/
	const updateAvailableWidth = useCallback(() => {
		if (!containerRef.current || typeof window === "undefined") return;
		const parent = containerRef.current.parentElement;
		if (!parent) {
			const containerRect = containerRef.current.getBoundingClientRect();
			setAvailableWidth(Math.floor(containerRect.width));
			return;
		}
		const parentStyle = window.getComputedStyle(parent);
		const parentRect = parent.getBoundingClientRect();
		const scale = parent.offsetWidth > 0 ? parentRect.width / parent.offsetWidth : 1;
		const paddingLeft = (parseFloat(parentStyle.paddingLeft) || 0) * scale;
		const paddingRight = (parseFloat(parentStyle.paddingRight) || 0) * scale;
		const parentGap = (parseFloat(parentStyle.gap) || gap) * scale;
		let leftSlotWidth = 0;
		if (leftSlotRef.current) {
			leftSlotWidth = Math.ceil(leftSlotRef.current.getBoundingClientRect().width);
			if (leftSlotWidth > 0) leftSlotWidth += parentGap;
		}
		let otherSiblingWidth = 0;
		const siblings = parent.children;
		for (let i = 0; i < siblings.length; i++) {
			const sibling = siblings[i];
			if (sibling !== containerRef.current && sibling !== leftSlotRef.current && !sibling.hasAttribute("aria-hidden")) {
				const siblingWidth = Math.ceil(sibling.getBoundingClientRect().width);
				if (siblingWidth > 0) otherSiblingWidth += siblingWidth + parentGap;
			}
		}
		const totalWidth = parentRect.width - paddingLeft - paddingRight;
		const width = Math.floor(totalWidth - leftSlotWidth - otherSiblingWidth);
		setAvailableWidth(Math.max(0, width));
	}, [gap]);
	/**
	* 初始化测量
	*/
	useEffect(() => {
		const rafId = requestAnimationFrame(() => {
			measureWidths();
			updateAvailableWidth();
		});
		return () => cancelAnimationFrame(rafId);
	}, [
		actionItems,
		measureWidths,
		updateAvailableWidth
	]);
	/**
	* 监听尺寸变化
	*/
	useEffect(() => {
		var _containerRef$current;
		if (typeof window === "undefined") return;
		const handleResize = () => {
			measureWidths();
			updateAvailableWidth();
		};
		window.addEventListener("resize", handleResize);
		const parent = (_containerRef$current = containerRef.current) === null || _containerRef$current === void 0 ? void 0 : _containerRef$current.parentElement;
		let resizeObserver = null;
		if (parent && typeof ResizeObserver !== "undefined") try {
			resizeObserver = new ResizeObserver(() => {
				measureWidths();
				updateAvailableWidth();
			});
			resizeObserver.observe(parent);
		} catch (error) {
			console.warn("Failed to create ResizeObserver:", error);
		}
		if (leftSlotRef.current && typeof ResizeObserver !== "undefined") try {
			const leftObserver = new ResizeObserver(() => updateAvailableWidth());
			leftObserver.observe(leftSlotRef.current);
			return () => {
				window.removeEventListener("resize", handleResize);
				resizeObserver === null || resizeObserver === void 0 || resizeObserver.disconnect();
				leftObserver.disconnect();
			};
		} catch (error) {
			console.warn("Failed to create ResizeObserver for leftSlot:", error);
		}
		return () => {
			window.removeEventListener("resize", handleResize);
			resizeObserver === null || resizeObserver === void 0 || resizeObserver.disconnect();
		};
	}, [measureWidths, updateAvailableWidth]);
	/**
	* 计算可见项数量
	* 根据可用宽度计算能显示多少个按钮
	*/
	const visibleCount = useMemo(() => {
		if (itemWidths.length === 0 || availableWidth === 0) return actionItems.length;
		const totalItems = itemWidths.length;
		if (itemWidths.reduce((sum, w) => sum + w, 0) + (totalItems - 1) * gap <= availableWidth) return totalItems;
		const spaceForButtons = availableWidth - moreButtonWidth - gap;
		if (spaceForButtons <= 0) return 0;
		let usedWidth = 0;
		let count = 0;
		for (let i = totalItems - 1; i >= 0; i--) {
			const requiredWidth = itemWidths[i] + (count > 0 ? gap : 0);
			if (usedWidth + requiredWidth <= spaceForButtons) {
				usedWidth += requiredWidth;
				count++;
			} else break;
		}
		return count;
	}, [
		itemWidths,
		availableWidth,
		gap,
		moreButtonWidth,
		actionItems.length
	]);
	const overflowCount = Math.max(0, actionItems.length - visibleCount);
	const overflowActions = actionItems.slice(0, overflowCount);
	return {
		containerRef,
		measureRef,
		moreButtonRef,
		leftSlotRef,
		actionItems,
		visibleActions: actionItems.slice(overflowCount),
		overflowActions,
		hasOverflow: overflowCount > 0,
		moreMenuItems: useMemo(() => {
			return overflowActions.map((action, index) => {
				if (!isValidElement(action)) return null;
				const buttonProps = action.props;
				const label = extractButtonLabel(buttonProps, `操作 ${index + 1}`);
				const originalOnClick = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.onClick;
				return {
					key: `overflow-${index}`,
					label,
					onClick: originalOnClick ? () => originalOnClick({}) : void 0,
					disabled: (buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.disabled) || (buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.loading),
					danger: buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.danger,
					icon: buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.icon,
					title: buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.title
				};
			}).filter(Boolean);
		}, [overflowActions]),
		availableWidth
	};
};
//#endregion
export { useOverflowActions };
