// Custom hooks
const { useEffect, useRef, useState } = React;

// Reveal-on-scroll
function useReveal(options = {}) {
  const ref = useRef(null);
  const [visible, setVisible] = useState(false);

  useEffect(() => {
    const node = ref.current;
    if (!node) return;
    const observer = new IntersectionObserver(
      ([entry]) => {
        if (entry.isIntersecting) {
          setVisible(true);
          observer.unobserve(node);
        }
      },
      { threshold: options.threshold || 0.15, rootMargin: options.rootMargin || "0px 0px -80px 0px" }
    );
    observer.observe(node);
    return () => observer.disconnect();
  }, []);

  return [ref, visible];
}

// Scrolled-past flag for nav
function useScrolled(threshold = 20) {
  const [scrolled, setScrolled] = useState(false);
  useEffect(() => {
    const onScroll = () => setScrolled(window.scrollY > threshold);
    onScroll();
    window.addEventListener("scroll", onScroll, { passive: true });
    return () => window.removeEventListener("scroll", onScroll);
  }, [threshold]);
  return scrolled;
}

// Theme management
function useTheme() {
  const [theme, setTheme] = useState(() => {
    if (typeof window === "undefined") return "dark";
    return localStorage.getItem("theme") || "dark";
  });

  useEffect(() => {
    document.documentElement.setAttribute("data-theme", theme);
    localStorage.setItem("theme", theme);
  }, [theme]);

  const toggle = () => setTheme((t) => (t === "dark" ? "light" : "dark"));
  return [theme, toggle];
}

// Typing effect for terminal lines
function useTyping(lines, speed = 18, lineDelay = 280) {
  const [output, setOutput] = useState([]);
  const [done, setDone] = useState(false);

  useEffect(() => {
    let cancelled = false;
    let lineIdx = 0;
    let charIdx = 0;
    setOutput([]);
    setDone(false);

    const tick = () => {
      if (cancelled) return;
      if (lineIdx >= lines.length) {
        setDone(true);
        return;
      }
      const line = lines[lineIdx];
      if (line.instant) {
        setOutput((prev) => [...prev, { ...line, partial: line.text }]);
        lineIdx++;
        charIdx = 0;
        setTimeout(tick, lineDelay);
        return;
      }
      const text = line.text || "";
      charIdx++;
      setOutput((prev) => {
        const copy = [...prev];
        copy[lineIdx] = { ...line, partial: text.slice(0, charIdx) };
        return copy;
      });
      if (charIdx >= text.length) {
        lineIdx++;
        charIdx = 0;
        setTimeout(tick, lineDelay);
      } else {
        setTimeout(tick, speed);
      }
    };

    const startTimer = setTimeout(tick, 600);
    return () => {
      cancelled = true;
      clearTimeout(startTimer);
    };
  }, []);

  return [output, done];
}

window.useReveal = useReveal;
window.useScrolled = useScrolled;
window.useTheme = useTheme;
window.useTyping = useTyping;
