import { useRef, useCallback } from 'react';

/**
 * Custom hook to synchronize horizontal scrolling between two scrollable containers.
 * When one container scrolls horizontally, the other will scroll to match.
 */
export const useSyncScroll = () => {
  const isScrollingRef = useRef(false);
  const firstElementRef = useRef<HTMLElement | null>(null);
  const secondElementRef = useRef<HTMLElement | null>(null);
  const cleanupRef = useRef<(() => void) | null>(null);

  const setupSync = useCallback(() => {
    const first = firstElementRef.current;
    const second = secondElementRef.current;

    if (!first || !second) {
      // Clean up if either element is missing
      if (cleanupRef.current) {
        cleanupRef.current();
        cleanupRef.current = null;
      }
      return;
    }

    // Clean up existing listeners if any
    if (cleanupRef.current) {
      cleanupRef.current();
    }

    const handleFirstScroll = () => {
      if (isScrollingRef.current) return;
      isScrollingRef.current = true;
      second.scrollLeft = first.scrollLeft;
      requestAnimationFrame(() => {
        isScrollingRef.current = false;
      });
    };

    const handleSecondScroll = () => {
      if (isScrollingRef.current) return;
      isScrollingRef.current = true;
      first.scrollLeft = second.scrollLeft;
      requestAnimationFrame(() => {
        isScrollingRef.current = false;
      });
    };

    first.addEventListener('scroll', handleFirstScroll);
    second.addEventListener('scroll', handleSecondScroll);

    cleanupRef.current = () => {
      first.removeEventListener('scroll', handleFirstScroll);
      second.removeEventListener('scroll', handleSecondScroll);
    };
  }, []);

  // Callback ref for first container
  const firstRefCallback = useCallback(
    (element: HTMLElement | null) => {
      firstElementRef.current = element;
      setupSync();
    },
    [setupSync],
  );

  // Callback ref for second container
  const secondRefCallback = useCallback(
    (element: HTMLElement | null) => {
      secondElementRef.current = element;
      setupSync();
    },
    [setupSync],
  );

  const scrollByAmount = useCallback((amount: number) => {
    const el = secondElementRef.current ?? firstElementRef.current;
    if (!el) return;
    el.scrollBy({ left: amount, behavior: 'smooth' });
  }, []);

  return { firstRefCallback, secondRefCallback, scrollByAmount };
};
