/*! © 2026 Yahoo, Inc. UDS v0.0.0-development */
"use client";
import { clampIndex, resolveHeightToPx } from "./utils.js";
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import { clamp } from "lodash-es";
//#region src/components/client/BottomSheet/useBottomSheetSnapModel.ts
const DEFAULT_SNAP_POINT = "40%";
const OPEN_SHEET_ENTER_DELAY_MS = 50;
function useBottomSheetSnapModel({ isOpen, snapPointsProp, height, defaultSnapPointIndex, snapPointIndexProp, onSnapPointChange, viewportHeightPx, maxHeightPx, setTranslateAnimated, isDraggingRef }) {
	const openTimeRef = useRef(null);
	const lastTimeDragPreventedRef = useRef(null);
	const openEnterTimeoutRef = useRef(null);
	const isEnteringRef = useRef(false);
	const resolvedSnapPoints = useMemo(() => {
		if (snapPointsProp?.length) return snapPointsProp;
		if (height !== void 0) return [height];
		return [DEFAULT_SNAP_POINT];
	}, [height, snapPointsProp]);
	const snapPointsPx = useMemo(() => {
		return resolvedSnapPoints.map((sp) => clamp(resolveHeightToPx(sp, viewportHeightPx), 0, maxHeightPx));
	}, [
		maxHeightPx,
		resolvedSnapPoints,
		viewportHeightPx
	]);
	const maxSnapPointPx = useMemo(() => Math.max(0, ...snapPointsPx), [snapPointsPx]);
	const snapPointTranslatesPx = useMemo(() => {
		return snapPointsPx.map((h) => maxSnapPointPx - h);
	}, [maxSnapPointPx, snapPointsPx]);
	const isSnapPointControlled = snapPointIndexProp !== void 0;
	const [uncontrolledSnapIndex, setUncontrolledSnapIndex] = useState(() => clampIndex(defaultSnapPointIndex, resolvedSnapPoints.length));
	const activeSnapIndex = clampIndex(isSnapPointControlled ? snapPointIndexProp ?? 0 : uncontrolledSnapIndex, resolvedSnapPoints.length);
	const activeTranslatePx = snapPointTranslatesPx[activeSnapIndex] ?? maxSnapPointPx;
	const [restTranslatePx, setRestTranslatePx] = useState(() => maxSnapPointPx);
	const lastEmittedTranslateRef = useRef(null);
	const emitSnapPointChange = useCallback((nextIndex) => {
		const clamped = clampIndex(nextIndex, resolvedSnapPoints.length);
		const nextTranslatePx = snapPointTranslatesPx[clamped] ?? maxSnapPointPx;
		onSnapPointChange?.(clamped, resolvedSnapPoints[clamped]);
		if (!isSnapPointControlled) setUncontrolledSnapIndex(clamped);
		setRestTranslatePx(nextTranslatePx);
		lastEmittedTranslateRef.current = nextTranslatePx;
		setTranslateAnimated(nextTranslatePx);
	}, [
		isSnapPointControlled,
		maxSnapPointPx,
		onSnapPointChange,
		resolvedSnapPoints,
		setTranslateAnimated,
		snapPointTranslatesPx
	]);
	useEffect(() => {
		const wasOpen = openTimeRef.current !== null;
		if (!isOpen) {
			if (openEnterTimeoutRef.current !== null) {
				window.clearTimeout(openEnterTimeoutRef.current);
				openEnterTimeoutRef.current = null;
			}
			isEnteringRef.current = false;
			openTimeRef.current = null;
			setRestTranslatePx(maxSnapPointPx);
			return;
		}
		if (wasOpen) return;
		isEnteringRef.current = true;
		openTimeRef.current = Date.now();
		const initialSnapIndex = isSnapPointControlled ? activeSnapIndex : clampIndex(defaultSnapPointIndex, resolvedSnapPoints.length);
		if (!isSnapPointControlled) setUncontrolledSnapIndex(initialSnapIndex);
		setRestTranslatePx(maxSnapPointPx);
		const initialTranslatePx = snapPointTranslatesPx[initialSnapIndex] ?? maxSnapPointPx;
		openEnterTimeoutRef.current = window.setTimeout(() => {
			isEnteringRef.current = false;
			setRestTranslatePx(initialTranslatePx);
			setTranslateAnimated(initialTranslatePx);
			openEnterTimeoutRef.current = null;
		}, OPEN_SHEET_ENTER_DELAY_MS);
	}, [
		activeSnapIndex,
		defaultSnapPointIndex,
		isOpen,
		isSnapPointControlled,
		maxSnapPointPx,
		resolvedSnapPoints.length,
		setTranslateAnimated,
		snapPointTranslatesPx
	]);
	useEffect(() => {
		return () => {
			if (openEnterTimeoutRef.current !== null) {
				window.clearTimeout(openEnterTimeoutRef.current);
				openEnterTimeoutRef.current = null;
			}
		};
	}, []);
	useEffect(() => {
		if (!isOpen || isEnteringRef.current || isDraggingRef.current) return;
		setRestTranslatePx(activeTranslatePx);
		if (lastEmittedTranslateRef.current === activeTranslatePx) {
			lastEmittedTranslateRef.current = null;
			return;
		}
		setTranslateAnimated(activeTranslatePx);
	}, [
		activeTranslatePx,
		isDraggingRef,
		isOpen,
		setTranslateAnimated
	]);
	useEffect(() => {
		if (!isOpen) return;
		if (activeSnapIndex === resolvedSnapPoints.length - 1) openTimeRef.current = Date.now();
	}, [
		activeSnapIndex,
		isOpen,
		resolvedSnapPoints.length
	]);
	return {
		resolvedSnapPoints,
		snapPointsPx,
		maxSnapPointPx,
		snapPointTranslatesPx,
		activeSnapIndex,
		restTranslatePx,
		setRestTranslatePx,
		isSnapPointControlled,
		emitSnapPointChange,
		openTimeRef,
		lastTimeDragPreventedRef,
		isEnteringRef
	};
}
//#endregion
export { useBottomSheetSnapModel };
