// UiUtils.jsx — shared mobile / dialog helpers.
const SITE_SECTION_LINKS = [
  { href: "#approach", label: "How We Work" },
  { href: "#work", label: "Case Studies" },
  { href: "#about", label: "Team" },
];

const SITE_EXTERNAL_LINKS = {
  email: "mailto:kyle@zaigo.ai",
  linkedIn: "https://www.linkedin.com/company/zaigo-ai/",
};

function useMobileLayout(maxWidth = 900) {
  const query = `(max-width: ${maxWidth}px)`;
  const [mobile, setMobile] = React.useState(() =>
    window.matchMedia(query).matches
  );

  React.useEffect(() => {
    const mq = window.matchMedia(query);
    const sync = () => setMobile(mq.matches);
    sync();
    mq.addEventListener("change", sync);
    return () => mq.removeEventListener("change", sync);
  }, [query]);

  return mobile;
}

function markVideoCached(src) {
  if (!src || window.ZG_VIDEO_CACHE.has(src)) return;
  window.ZG_VIDEO_CACHE.add(src);
  window.dispatchEvent(new CustomEvent("zg-video-cached", { detail: { src } }));
}

function isVideoCached(src) {
  return Boolean(src && window.ZG_VIDEO_CACHE.has(src));
}

function useVideoCached(src) {
  const [cached, setCached] = React.useState(() => isVideoCached(src));

  React.useEffect(() => {
    setCached(isVideoCached(src));
    if (!src) return undefined;

    const onCached = (event) => {
      if (event.detail?.src === src) setCached(true);
    };

    window.addEventListener("zg-video-cached", onCached);
    return () => window.removeEventListener("zg-video-cached", onCached);
  }, [src]);

  return cached;
}

function useInViewVideo(videoRef, enabled) {
  React.useEffect(() => {
    const el = videoRef.current;
    if (!el || enabled === false) return undefined;

    const motion = window.matchMedia("(prefers-reduced-motion: reduce)");

    const sync = (shouldPlay) => {
      if (!shouldPlay || motion.matches) {
        el.pause();
        return;
      }
      el.play().catch(() => {});
    };

    const onLoaded = () => markVideoCached(el.currentSrc || el.src);
    const onMotion = () => sync(true);
    motion.addEventListener("change", onMotion);
    el.addEventListener("loadeddata", onLoaded);

    const io = new IntersectionObserver(
      ([entry]) => {
        sync(entry.isIntersecting && entry.intersectionRatio >= 0.2);
      },
      { threshold: [0, 0.2, 0.45] }
    );

    io.observe(el);
    return () => {
      motion.removeEventListener("change", onMotion);
      el.removeEventListener("loadeddata", onLoaded);
      io.disconnect();
      el.pause();
    };
  }, [enabled, videoRef]);
}

function useFocusTrap(active, containerRef, onClose) {
  const triggerRef = React.useRef(null);

  React.useEffect(() => {
    if (!active) return undefined;

    triggerRef.current = document.activeElement;
    const root = document.querySelector(".zg-page");
    if (root) root.setAttribute("inert", "");

    const container = containerRef.current;
    const focusables = () =>
      container
        ? Array.from(
            container.querySelectorAll(
              'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
            )
          ).filter((node) => !node.hasAttribute("disabled"))
        : [];

    const focusFirst = () => {
      const nodes = focusables();
      (nodes[0] || container)?.focus?.();
    };

    const id = window.requestAnimationFrame(focusFirst);

    const onKey = (event) => {
      if (event.key === "Escape") {
        onClose();
        return;
      }
      if (event.key !== "Tab" || !container) return;

      const nodes = focusables();
      if (!nodes.length) return;

      const first = nodes[0];
      const last = nodes[nodes.length - 1];

      if (event.shiftKey && document.activeElement === first) {
        event.preventDefault();
        last.focus();
      } else if (!event.shiftKey && document.activeElement === last) {
        event.preventDefault();
        first.focus();
      }
    };

    document.addEventListener("keydown", onKey);
    return () => {
      window.cancelAnimationFrame(id);
      document.removeEventListener("keydown", onKey);
      if (root) root.removeAttribute("inert");
      if (triggerRef.current?.focus) {
        triggerRef.current.focus();
      }
    };
  }, [active, containerRef, onClose]);
}

window.SITE_SECTION_LINKS = SITE_SECTION_LINKS;
window.SITE_EXTERNAL_LINKS = SITE_EXTERNAL_LINKS;
window.ZG_VIDEO_CACHE = window.ZG_VIDEO_CACHE || new Set();
window.markVideoCached = markVideoCached;
window.isVideoCached = isVideoCached;
window.useMobileLayout = useMobileLayout;
window.useVideoCached = useVideoCached;
window.useInViewVideo = useInViewVideo;
window.useFocusTrap = useFocusTrap;
