/* ui.jsx — shared primitives: scroll-reveal, media hook, small helpers */
const { useState, useEffect, useRef, useCallback } = React;

/* Reveal-on-scroll wrapper */
function Reveal({ children, className = '', delay = 0, tag = 'div', ...rest }) {
  const ref = useRef(null);
  const [seen, setSeen] = useState(false);
  useEffect(() => {
    const el = ref.current;
    if (!el) return;
    const io = new IntersectionObserver((entries) => {
      entries.forEach((e) => { if (e.isIntersecting) { setSeen(true); io.disconnect(); } });
    }, { threshold: 0.18 });
    io.observe(el);
    return () => io.disconnect();
  }, []);
  const Tag = tag;
  const d = delay ? ` d${delay}` : '';
  return <Tag ref={ref} className={`reveal${d} ${seen ? 'in' : ''} ${className}`} {...rest}>{children}</Tag>;
}

/* live media list, re-reads on the global 'r50:media' event */
function useMediaList(filter) {
  const [items, setItems] = useState([]);
  const load = useCallback(async () => {
    const all = await R50.getMedia();
    setItems(filter ? all.filter(filter) : all);
  }, [filter]);
  useEffect(() => {
    load();
    const h = () => load();
    window.addEventListener('r50:media', h);
    return () => window.removeEventListener('r50:media', h);
  }, [load]);
  return items;
}

function bumpMedia() { window.dispatchEvent(new Event('r50:media')); }

/* read a file from an <input> or drop, with basic guard rails */
function pickFile(onFile, { accept } = {}) {
  const input = document.createElement('input');
  input.type = 'file';
  if (accept) input.accept = accept;
  input.onchange = () => { if (input.files && input.files[0]) onFile(input.files[0]); };
  input.click();
}

const SECTION_LINKS = [
  ['Invitation', 'invitation'],
  ['Details', 'details'],
  ['RSVP', 'rsvp'],
  ['Guestbook', 'guestbook'],
  ['Gallery', 'gallery'],
];

Object.assign(window, { Reveal, useMediaList, bumpMedia, pickFile, SECTION_LINKS });
