"use client";

import { useCallback, useEffect, useRef, useState } from "react";

interface UseSnapCarouselOptions {
  total: number;
  autoPlayMs?: number;
}

export function useSnapCarousel({ total, autoPlayMs = 10000 }: UseSnapCarouselOptions) {
  const scrollRef = useRef<HTMLDivElement>(null);
  const [activeIndex, setActiveIndex] = useState(0);
  const totalRef = useRef(total);
  totalRef.current = total;

  const pausedRef = useRef(false);
  const pauseTimerRef = useRef<ReturnType<typeof setTimeout>>(undefined);

  const pauseAutoPlay = useCallback(() => {
    pausedRef.current = true;
    clearTimeout(pauseTimerRef.current);
    pauseTimerRef.current = setTimeout(() => {
      pausedRef.current = false;
    }, autoPlayMs * 2);
  }, [autoPlayMs]);

  const getCurrentIndex = useCallback(() => {
    const el = scrollRef.current;
    if (!el || el.offsetWidth === 0) return 0;
    return Math.round(el.scrollLeft / el.offsetWidth);
  }, []);

  // Sync activeIndex from scroll position (rAF-throttled)
  useEffect(() => {
    const container = scrollRef.current;
    if (!container) return;

    let rafId = 0;
    const onScroll = () => {
      cancelAnimationFrame(rafId);
      rafId = requestAnimationFrame(() => {
        const index = getCurrentIndex();
        setActiveIndex(Math.min(index, totalRef.current - 1));
      });
    };

    container.addEventListener("scroll", onScroll, { passive: true });
    return () => {
      container.removeEventListener("scroll", onScroll);
      cancelAnimationFrame(rafId);
    };
  }, [getCurrentIndex]);

  const scrollToIndex = useCallback((index: number) => {
    const container = scrollRef.current;
    if (!container) return;
    container.scrollTo({ left: index * container.offsetWidth, behavior: "smooth" });
  }, []);

  const goTo = useCallback(
    (index: number) => {
      pauseAutoPlay();
      scrollToIndex(index);
    },
    [pauseAutoPlay, scrollToIndex]
  );

  const goNext = useCallback(() => {
    pauseAutoPlay();
    scrollToIndex((getCurrentIndex() + 1) % totalRef.current);
  }, [pauseAutoPlay, scrollToIndex, getCurrentIndex]);

  const goPrev = useCallback(() => {
    pauseAutoPlay();
    scrollToIndex((getCurrentIndex() - 1 + totalRef.current) % totalRef.current);
  }, [pauseAutoPlay, scrollToIndex, getCurrentIndex]);

  const reset = useCallback(() => {
    const container = scrollRef.current;
    if (!container) return;
    container.scrollTo({ left: 0, behavior: "instant" });
    setActiveIndex(0);
  }, []);

  // Auto-play
  useEffect(() => {
    if (total <= 1) return;
    const id = setInterval(() => {
      if (pausedRef.current) return;
      const next = (getCurrentIndex() + 1) % totalRef.current;
      scrollToIndex(next);
    }, autoPlayMs);
    return () => clearInterval(id);
  }, [total, autoPlayMs, getCurrentIndex, scrollToIndex]);

  const onPointerDown = useCallback(() => {
    pauseAutoPlay();
  }, [pauseAutoPlay]);

  const onKeyDown = useCallback(
    (e: React.KeyboardEvent) => {
      if (e.key === "ArrowLeft") goPrev();
      else if (e.key === "ArrowRight") goNext();
    },
    [goPrev, goNext]
  );

  // Cleanup pause timer
  useEffect(() => {
    return () => clearTimeout(pauseTimerRef.current);
  }, []);

  return {
    scrollRef,
    activeIndex,
    total,
    goTo,
    goNext,
    goPrev,
    reset,
    onPointerDown,
    onKeyDown,
  };
}
