"use client";

import { useEffect, useRef, type RefObject } from "react";

export interface MouseVectorPoint {
  x: number;
  y: number;
}

/**
 * Reports mouse position **relative to `containerRef`'s own bounding
 * rect** — never `window`/page-relative coordinates. This is the fix for
 * the classic image-trail demo mistake: listening on `window` means the
 * trail spawns anywhere on the page instead of staying clipped inside its
 * own card.
 *
 * `onMove` only fires once the pointer has moved at least `minDistance`
 * px since the last report, so callers can use it directly as a spawn-
 * rate throttle instead of reacting to every raw `mousemove` tick (which
 * fires far more often than needed for a visual trail).
 */
export function useMouseVector(
  containerRef: RefObject<HTMLElement | null>,
  onMove: (point: MouseVectorPoint) => void,
  { minDistance = 40, enabled = true }: { minDistance?: number; enabled?: boolean } = {},
) {
  const lastPoint = useRef<MouseVectorPoint | null>(null);
  const onMoveRef = useRef(onMove);

  useEffect(() => {
    onMoveRef.current = onMove;
  }, [onMove]);

  useEffect(() => {
    if (!enabled) return;

    const container = containerRef.current;
    if (!container) return;

    function handleMove(e: MouseEvent) {
      const rect = container!.getBoundingClientRect();
      const point: MouseVectorPoint = { x: e.clientX - rect.left, y: e.clientY - rect.top };

      const last = lastPoint.current;
      const distance = last ? Math.hypot(point.x - last.x, point.y - last.y) : Infinity;

      if (distance >= minDistance) {
        lastPoint.current = point;
        onMoveRef.current(point);
      }
    }

    container.addEventListener("mousemove", handleMove);
    return () => container.removeEventListener("mousemove", handleMove);
  }, [containerRef, enabled, minDistance]);
}
