import { useEffect, useRef, useCallback } from 'react';

type UseScrollRestorationOptions = {
  scrollPosition: number;
  containerId: string;
  maxLayoutShifts?: number;
  layoutShiftDelay?: number;
  disabled?: boolean;
};

export const useScrollRestoration = ({
  scrollPosition,
  containerId,
  maxLayoutShifts = 5,
  layoutShiftDelay = 100,
  disabled = false,
}: UseScrollRestorationOptions) => {
  const layoutShiftCountRef = useRef(0);
  const observersRef = useRef<{
    resizeObserver?: ResizeObserver;
    intersectionObserver?: IntersectionObserver;
  }>({});

  const cleanupScrollRestoration = useCallback(() => {
    const { resizeObserver, intersectionObserver } = observersRef.current;

    if (resizeObserver) {
      resizeObserver.disconnect();
    }
    if (intersectionObserver) {
      intersectionObserver.disconnect();
    }

    // Clean up event listeners
    const element = document.getElementById(containerId);
    if (element) {
      const images = element.querySelectorAll('img');
      images.forEach(img => {
        img.removeEventListener('load', handleLayoutShift);
      });
    }

    observersRef.current = {};
  }, [containerId]);

  const handleLayoutShift = useCallback(() => {
    if (layoutShiftCountRef.current < maxLayoutShifts && !disabled) {
      layoutShiftCountRef.current++;
      const element = document.getElementById(containerId);
      if (element) {
        setTimeout(() => {
          element.scrollTo(0, scrollPosition);
        }, layoutShiftDelay);
      }
    }
  }, [containerId, scrollPosition, maxLayoutShifts, layoutShiftDelay]);

  const setupScrollRestoration = useCallback(() => {
    if (disabled || scrollPosition <= 0) return;

    const element = document.getElementById(containerId);
    if (!element) return;

    // Reset layout shift counter
    layoutShiftCountRef.current = 0;

    // Initial scroll
    requestAnimationFrame(() => {
      element.scrollTo(0, scrollPosition);
    });

    // Set up observers
    const resizeObserver = new ResizeObserver(() => {
      handleLayoutShift();
    });

    const intersectionObserver = new IntersectionObserver(
      entries => {
        entries.forEach(entry => {
          if (entry.isIntersecting) {
            const img = entry.target as HTMLImageElement;
            if (img.complete && img.naturalHeight > 0) {
              handleLayoutShift();
            }
          }
        });
      },
      { root: element },
    );

    // Observe all images in the container
    const images = element.querySelectorAll('img');
    images.forEach(img => {
      resizeObserver.observe(img);
      intersectionObserver.observe(img);
      img.addEventListener('load', handleLayoutShift);
    });
  }, [scrollPosition, containerId, handleLayoutShift, disabled]);

  useEffect(() => {
    setupScrollRestoration();
    return () => {
      cleanupScrollRestoration();
    };
  }, [setupScrollRestoration, cleanupScrollRestoration]);
};
