import { useCallback, useRef } from "react";
//#region src/components/pisellTimeNavigator/hooks/useDragInertia.ts
const DECAY = .95;
const MIN_VELOCITY = .5;
const SAMPLE_MS = 50;
/**
* 惯性滚动：根据拖动末段速度在松手后继续滚动并衰减
*/
function useDragInertia(options) {
	const { enabled, orientation, getScrollContainer } = options;
	const rafId = useRef(null);
	const lastPos = useRef(0);
	const lastTime = useRef(0);
	const velocity = useRef(0);
	const samples = useRef([]);
	const applyScroll = useCallback((delta) => {
		const el = getScrollContainer();
		if (!el) return;
		if (orientation === "horizontal") el.scrollLeft = Math.max(0, el.scrollLeft + delta);
		else el.scrollTop = Math.max(0, el.scrollTop + delta);
	}, [getScrollContainer, orientation]);
	const lastTickTime = useRef(0);
	const tick = useCallback((now) => {
		const t = now !== null && now !== void 0 ? now : performance.now();
		const dt = lastTickTime.current ? (t - lastTickTime.current) / 1e3 : .016;
		lastTickTime.current = t;
		const v = velocity.current;
		if (Math.abs(v) < MIN_VELOCITY) {
			velocity.current = 0;
			lastTickTime.current = 0;
			return;
		}
		applyScroll(v * dt);
		velocity.current = v * DECAY;
		rafId.current = requestAnimationFrame(tick);
	}, [applyScroll]);
	const stopInertia = useCallback(() => {
		if (rafId.current != null) {
			cancelAnimationFrame(rafId.current);
			rafId.current = null;
		}
		velocity.current = 0;
		samples.current = [];
	}, []);
	return {
		onPointerDown: useCallback((e) => {
			if (!enabled) return;
			stopInertia();
			const pos = orientation === "horizontal" ? e.clientX : e.clientY;
			lastPos.current = pos;
			lastTime.current = Date.now();
			samples.current = [{
				pos,
				t: lastTime.current
			}];
		}, [
			enabled,
			orientation,
			stopInertia
		]),
		onPointerMove: useCallback((e) => {
			if (!enabled) return;
			const pos = orientation === "horizontal" ? e.clientX : e.clientY;
			const t = Date.now();
			const el = getScrollContainer();
			if (el) {
				const scroll = orientation === "horizontal" ? el.scrollLeft : el.scrollTop;
				const delta = pos - lastPos.current;
				const maxScroll = orientation === "horizontal" ? el.scrollWidth - el.clientWidth : el.scrollHeight - el.clientHeight;
				const next = Math.max(0, Math.min(maxScroll, scroll + delta));
				if (orientation === "horizontal") el.scrollLeft = next;
				else el.scrollTop = next;
			}
			lastPos.current = pos;
			lastTime.current = t;
			samples.current.push({
				pos,
				t
			});
			const cutoff = t - SAMPLE_MS;
			while (samples.current.length > 1 && samples.current[0].t < cutoff) samples.current.shift();
		}, [
			enabled,
			orientation,
			getScrollContainer
		]),
		onPointerUp: useCallback((e) => {
			if (!enabled) return;
			const arr = samples.current;
			if (arr.length < 2) return;
			const first = arr[0];
			const last = arr[arr.length - 1];
			const dt = (last.t - first.t) / 1e3;
			if (dt <= 0) return;
			const scrollEl = getScrollContainer();
			if (!scrollEl) return;
			orientation === "horizontal" ? scrollEl.scrollLeft : scrollEl.scrollTop;
			velocity.current = (last.pos - first.pos) / dt;
			stopInertia();
			rafId.current = requestAnimationFrame(tick);
		}, [
			enabled,
			orientation,
			getScrollContainer,
			stopInertia,
			tick
		]),
		stopInertia
	};
}
//#endregion
export { useDragInertia };
