import { useCallback, useRef, useState } from "react"

export type ResizeEdge = "left" | "right"

interface UseSegmentResizeOptions {
	pixelsPerSecond: number
	onResize: (index: number, edge: ResizeEdge, deltaSec: number) => void
	onResizeEnd: (index: number, edge: ResizeEdge) => void
}

export function useSegmentResize({
	pixelsPerSecond,
	onResize,
	onResizeEnd,
}: UseSegmentResizeOptions) {
	const [resizingIndex, setResizingIndex] = useState(-1)
	const [resizingEdge, setResizingEdge] = useState<ResizeEdge | null>(null)

	const startXRef = useRef(0)
	const accDeltaRef = useRef(0)
	const indexRef = useRef(-1)
	const edgeRef = useRef<ResizeEdge>("left")
	const ppsRef = useRef(pixelsPerSecond)
	ppsRef.current = pixelsPerSecond

	// Use refs for callbacks to avoid stale closures in event listeners
	const onResizeRef = useRef(onResize)
	onResizeRef.current = onResize
	const onResizeEndRef = useRef(onResizeEnd)
	onResizeEndRef.current = onResizeEnd

	const justResizedRef = useRef(false)

	// Stable references that never change — safe for addEventListener/removeEventListener
	const moveHandlerRef = useRef<((e: PointerEvent) => void) | null>(null)
	const upHandlerRef = useRef<((e: PointerEvent) => void) | null>(null)

	if (!moveHandlerRef.current) {
		moveHandlerRef.current = (e: PointerEvent) => {
			const dx = e.clientX - startXRef.current
			const deltaSec = dx / ppsRef.current
			const prevDelta = accDeltaRef.current
			const incrementalDelta = deltaSec - prevDelta
			accDeltaRef.current = deltaSec
			onResizeRef.current(indexRef.current, edgeRef.current, incrementalDelta)
		}
	}

	if (!upHandlerRef.current) {
		upHandlerRef.current = (e: PointerEvent) => {
			document.removeEventListener("pointermove", moveHandlerRef.current!)
			document.removeEventListener("pointerup", upHandlerRef.current!)

			onResizeEndRef.current(indexRef.current, edgeRef.current)
			setResizingIndex(-1)
			setResizingEdge(null)

			justResizedRef.current = true
			setTimeout(() => {
				justResizedRef.current = false
			}, 200)
		}
	}

	const handlePointerDown = useCallback(
		(e: React.PointerEvent, index: number, edge: ResizeEdge) => {
			e.stopPropagation()
			e.preventDefault()

			startXRef.current = e.clientX
			accDeltaRef.current = 0
			indexRef.current = index
			edgeRef.current = edge

			setResizingIndex(index)
			setResizingEdge(edge)

			document.addEventListener("pointermove", moveHandlerRef.current!)
			document.addEventListener("pointerup", upHandlerRef.current!)
		},
		[],
	)

	return {
		handlePointerDown,
		resizingIndex,
		resizingEdge,
		justResizedRef,
	}
}
