import React, { createContext, useCallback, useContext, useEffect, useMemo, useRef, useState } from "react";
//#region src/pro/Selector/components/IntersectionObserver.tsx
/**
* IntersectionObserver 组件
* 用于监听一组 DOM 元素的可见性状态，并获取第一个可见元素的索引。
* @example
* function App() {
*   return (
*     <IntersectionObserverProvider
*       onFirstVisibleIndexChange={(index) => {
*         console.log('第一个可见元素的索引:', index);
*       }}
*       rootMargin="0px 0px -10% 0px" // 自定义根边距
*     >
*       <ScrollContainer>
*         {items.map((item, index) => (
*           <IntersectionItem key={item.id} index={index}>
*             <ItemComponent data={item} />
*           </IntersectionItem>
*         ))}
*       </ScrollContainer>
*     </IntersectionObserverProvider>
*   );
* }
*/
/**
* 简易 useMemoizedFn hook
*/
function useMemoizedFn(fn) {
	const fnRef = useRef(fn);
	const memoizedFn = useRef();
	fnRef.current = fn;
	if (!memoizedFn.current) memoizedFn.current = ((...args) => {
		return fnRef.current(...args);
	});
	return memoizedFn.current;
}
/**
* IntersectionObserver 上下文
*/
const IntersectionObserverContext = createContext({
	initialized: false,
	registerElement: () => {},
	unregisterElement: () => {},
	registerElements: () => {},
	clearAll: () => {},
	firstVisibleIndex: -1
});
const IntersectionObserverProvider = ({ children, root = null, rootMargin = "0px", threshold = 0, onFirstVisibleIndexChange, disabled = false }) => {
	const [initialized, setInitialized] = useState(false);
	const [firstVisibleIndex, setFirstVisibleIndex] = useState(-1);
	const observerRef = useRef(null);
	const elementsMapRef = useRef(/* @__PURE__ */ new Map());
	const pendingRegistrationsRef = useRef([]);
	const firstVisibleIndexRef = useRef(-1);
	const onFirstVisibleIndexChangeRef = useRef(onFirstVisibleIndexChange);
	useEffect(() => {
		onFirstVisibleIndexChangeRef.current = onFirstVisibleIndexChange;
	});
	useEffect(() => {
		firstVisibleIndexRef.current = firstVisibleIndex;
	});
	/**
	* 计算第一个可见元素的索引
	*/
	const calculateFirstVisibleIndex = useCallback(() => {
		let minIndex = -1;
		elementsMapRef.current.forEach((elementInfo) => {
			if (elementInfo.isVisible) {
				if (minIndex === -1 || elementInfo.index < minIndex) minIndex = elementInfo.index;
			}
		});
		return minIndex;
	}, []);
	/**
	* 更新第一个可见元素索引
	*/
	const updateFirstVisibleIndex = useMemoizedFn(() => {
		const newIndex = calculateFirstVisibleIndex();
		if (newIndex !== firstVisibleIndexRef.current) {
			var _onFirstVisibleIndexC;
			setFirstVisibleIndex(newIndex);
			(_onFirstVisibleIndexC = onFirstVisibleIndexChangeRef.current) === null || _onFirstVisibleIndexC === void 0 || _onFirstVisibleIndexC.call(onFirstVisibleIndexChangeRef, newIndex);
		}
	});
	/**
	* 创建 IntersectionObserver 实例
	*/
	const observerOptions = useMemo(() => ({
		root,
		rootMargin,
		threshold
	}), [
		root,
		rootMargin,
		threshold
	]);
	const createObserver = useCallback(() => {
		if (disabled) return null;
		if (typeof window === "undefined" || !window.IntersectionObserver) {
			console.warn("IntersectionObserver is not supported in this browser");
			return null;
		}
		return new IntersectionObserver((entries) => {
			let hasChanged = false;
			entries.forEach((entry) => {
				const elementInfo = elementsMapRef.current.get(entry.target);
				if (elementInfo) {
					const wasVisible = elementInfo.isVisible;
					const isVisible = entry.isIntersecting;
					if (wasVisible !== isVisible) {
						elementInfo.isVisible = isVisible;
						hasChanged = true;
					}
				}
			});
			if (hasChanged) updateFirstVisibleIndex();
		}, observerOptions);
	}, [observerOptions, disabled]);
	/**
	* 实际执行注册逻辑
	*/
	const doRegisterElement = useCallback((element, index) => {
		if (!observerRef.current || !element) return false;
		if (elementsMapRef.current.has(element)) {
			const elementInfo = elementsMapRef.current.get(element);
			if (elementInfo.index !== index) elementInfo.index = index;
			return true;
		}
		const elementInfo = {
			element,
			index,
			isVisible: false
		};
		elementsMapRef.current.set(element, elementInfo);
		observerRef.current.observe(element);
		return true;
	}, []);
	/**
	* 处理待注册队列中的元素
	*/
	const processPendingRegistrations = useMemoizedFn(() => {
		const pending = pendingRegistrationsRef.current;
		pendingRegistrationsRef.current = [];
		pending.forEach(({ element, index }) => {
			doRegisterElement(element, index);
		});
	});
	/**
	* 注册元素
	*/
	const registerElement = useCallback((element, index) => {
		if (!element) return;
		if (observerRef.current) {
			doRegisterElement(element, index);
			return;
		}
		const existingIndex = pendingRegistrationsRef.current.findIndex((item) => item.element === element);
		if (existingIndex === -1) pendingRegistrationsRef.current.push({
			element,
			index
		});
		else pendingRegistrationsRef.current[existingIndex].index = index;
	}, [doRegisterElement]);
	/**
	* 注销元素
	*/
	const unregisterElement = useCallback((element) => {
		if (!element) return;
		const pendingIndex = pendingRegistrationsRef.current.findIndex((item) => item.element === element);
		if (pendingIndex !== -1) pendingRegistrationsRef.current.splice(pendingIndex, 1);
		if (observerRef.current && elementsMapRef.current.has(element)) {
			elementsMapRef.current.delete(element);
			observerRef.current.unobserve(element);
			updateFirstVisibleIndex();
		}
	}, []);
	/**
	* 批量注册元素
	*/
	const registerElements = useCallback((elements) => {
		elements.forEach(({ element, index }) => {
			registerElement(element, index);
		});
	}, [registerElement]);
	/**
	* 清除所有注册的元素
	*/
	const clearAll = useCallback(() => {
		pendingRegistrationsRef.current = [];
		if (observerRef.current) elementsMapRef.current.forEach((_, element) => {
			observerRef.current.unobserve(element);
		});
		elementsMapRef.current.clear();
		updateFirstVisibleIndex();
	}, []);
	/**
	* 初始化 IntersectionObserver
	*/
	useEffect(() => {
		const observer = createObserver();
		if (observer) {
			observerRef.current = observer;
			processPendingRegistrations();
			setInitialized(true);
		}
		return () => {
			if (observerRef.current) {
				observerRef.current.disconnect();
				observerRef.current = null;
			}
			elementsMapRef.current.clear();
			pendingRegistrationsRef.current = [];
			setInitialized(false);
			setFirstVisibleIndex(-1);
		};
	}, [createObserver]);
	const contextValue = useMemo(() => ({
		initialized,
		registerElement,
		unregisterElement,
		registerElements,
		clearAll,
		firstVisibleIndex
	}), [
		initialized,
		registerElement,
		unregisterElement,
		registerElements,
		clearAll,
		firstVisibleIndex
	]);
	return /* @__PURE__ */ React.createElement(IntersectionObserverContext.Provider, { value: contextValue }, children);
};
/**
* 使用 IntersectionObserver 的 Hook
* @returns {Object} 包含注册元素函数和第一个可见元素索引的对象
*/
const useIntersectionObserver = () => {
	const context = useContext(IntersectionObserverContext);
	if (!context) throw new Error("useIntersectionObserver must be used within IntersectionObserverProvider");
	return context;
};
/**
* IntersectionItem 组件
* 自动注册元素到 IntersectionObserver 中
*/
const IntersectionItem = ({ index, children, className, style }) => {
	const elementRef = useRef(null);
	const { initialized, registerElement, unregisterElement } = useIntersectionObserver();
	useEffect(() => {
		const element = elementRef.current;
		if (initialized && element) {
			registerElement(element, index);
			return () => {
				unregisterElement(element);
			};
		}
	}, [
		initialized,
		index,
		registerElement,
		unregisterElement
	]);
	return /* @__PURE__ */ React.createElement("div", {
		ref: elementRef,
		className,
		style
	}, children);
};
//#endregion
export { IntersectionItem, IntersectionObserverProvider as default };
