import {
	type MouseEvent,
	type TouchEvent,
	useEffect,
	useRef,
	useState,
} from "react";

export interface UseComparisonSliderResult {
	position: number;
	setPosition: React.Dispatch<React.SetStateAction<number>>;
	containerRef: React.RefObject<HTMLDivElement>;
	isDragging: boolean;
	handleMouseDown: (e: MouseEvent) => void;
	handleTouchStart: (e: TouchEvent) => void;
}

export function useComparisonSlider(
	defaultPosition: number,
	direction: "horizontal" | "vertical",
): UseComparisonSliderResult {
	const [position, setPosition] = useState(defaultPosition);
	const containerRef = useRef<HTMLDivElement>(null);
	const [isDragging, setIsDragging] = useState(false);

	const updatePositionFromEvent = (clientX: number, clientY: number) => {
		if (!containerRef.current) return;
		const { left, top, width, height } =
			containerRef.current.getBoundingClientRect();
		if (direction === "horizontal") {
			const newPosition = ((clientX - left) / width) * 100;
			setPosition(Math.min(Math.max(newPosition, 0), 100));
		} else {
			const newPosition = ((clientY - top) / height) * 100;
			setPosition(Math.min(Math.max(newPosition, 0), 100));
		}
	};

	const handleMouseDown = (e: MouseEvent) => {
		e.preventDefault();
		setIsDragging(true);
		updatePositionFromEvent(e.clientX, e.clientY);
	};

	const handleTouchStart = (e: TouchEvent) => {
		setIsDragging(true);
		updatePositionFromEvent(e.touches[0].clientX, e.touches[0].clientY);
	};

	useEffect(() => {
		const handleMouseMove = (e: globalThis.MouseEvent) => {
			if (isDragging) {
				updatePositionFromEvent(e.clientX, e.clientY);
			}
		};
		const handleTouchMove = (e: globalThis.TouchEvent) => {
			if (isDragging && e.touches[0]) {
				updatePositionFromEvent(e.touches[0].clientX, e.touches[0].clientY);
			}
		};
		const handleMouseUp = () => {
			setIsDragging(false);
		};
		if (isDragging) {
			window.addEventListener("mousemove", handleMouseMove);
			window.addEventListener("touchmove", handleTouchMove);
			window.addEventListener("mouseup", handleMouseUp);
			window.addEventListener("touchend", handleMouseUp);
		}
		return () => {
			window.removeEventListener("mousemove", handleMouseMove);
			window.removeEventListener("touchmove", handleTouchMove);
			window.removeEventListener("mouseup", handleMouseUp);
			window.removeEventListener("touchend", handleMouseUp);
		};
	}, [isDragging, updatePositionFromEvent]);

	return {
		position,
		setPosition,
		containerRef,
		isDragging,
		handleMouseDown,
		handleTouchStart,
	};
}
