import { useScrollHandler } from "contexts/ScrollHandlerContext";
import { useEffect, useRef } from "react";

export default function ScrollEventHandler() {
  const { 
    setShowScrollTop, 
    setIsCategoriesSticky, 
    categoriesContainerRef,
    categoryRefs,
    activeCategory,
    setActiveCategory 
  } = useScrollHandler();

  const hasSetInitialCategory = useRef(false);

  // Set initial active category when categories are available
  useEffect(() => {
    if (categoryRefs.current && Object.keys(categoryRefs.current).length > 0 && !hasSetInitialCategory.current) {
      // Set the first category as active initially
      const firstCategoryId = parseInt(Object.keys(categoryRefs.current)[0]);
      setActiveCategory(firstCategoryId);
      hasSetInitialCategory.current = true;
    }
  }, [categoryRefs, setActiveCategory]);

  useEffect(() => {
    const handleScroll = () => {
      const scrollTop =
        window.pageYOffset || document.documentElement.scrollTop;
      setShowScrollTop(scrollTop > 300); // Show button after scrolling 300px

      // Check if we should make categories sticky
      if (categoriesContainerRef.current) {
        // Get the original position of the categories container
        const originalTop = categoriesContainerRef.current.offsetTop;

        // Only make sticky when we've scrolled past the original position
        // and return to normal when we scroll back above it
        // Add a small threshold (10px) to prevent flickering
        const shouldBeSticky = scrollTop > originalTop + 10;
        setIsCategoriesSticky(shouldBeSticky);
      }

      // Find the most visible category based on scroll position
      if (categoryRefs.current) {
        let mostVisibleCategory: { id: number; visibility: number } | null = null;
        
        Object.entries(categoryRefs.current).forEach(([categoryId, element]) => {
          if (element) {
            const rect = element.getBoundingClientRect();
            const viewportHeight = window.innerHeight;
            
            // Calculate visibility ratio
            const elementTop = rect.top;
            const elementBottom = rect.bottom;
            const elementHeight = rect.height;
            
            // Calculate how much of the element is visible
            let visibleHeight = 0;
            if (elementTop >= 0 && elementBottom <= viewportHeight) {
              // Element is fully visible
              visibleHeight = elementHeight;
            } else if (elementTop < 0 && elementBottom > 0) {
              // Element is partially visible from top
              visibleHeight = elementBottom;
            } else if (elementTop < viewportHeight && elementBottom > viewportHeight) {
              // Element is partially visible from bottom
              visibleHeight = viewportHeight - elementTop;
            }
            
            const visibility = visibleHeight / elementHeight;
            
            // Only consider elements that are at least 30% visible
            if (visibility > 0.3) {
              if (!mostVisibleCategory || visibility > mostVisibleCategory.visibility) {
                mostVisibleCategory = {
                  id: parseInt(categoryId),
                  visibility
                };
              }
            }
          }
        });
        
        // Update active category if we found a visible one
        if (mostVisibleCategory) {
          setActiveCategory((mostVisibleCategory as { id: number; visibility: number }).id);
        }
      }
    };

    window.addEventListener("scroll", handleScroll);
    return () => window.removeEventListener("scroll", handleScroll);
  }, [categoriesContainerRef, setIsCategoriesSticky, setShowScrollTop, categoryRefs, setActiveCategory, activeCategory]);

  return null;
}
