// Shared UI helpers for the PRLX website kit — exported to window.

// Lucide icon as a React element
function Icon({ name, size = 18, style = {} }) {
  return (
    <span
      style={{ display: "inline-flex", lineHeight: 0, ...style }}
      ref={(el) => {
        if (!el || !window.lucide || !lucide[name]) return;
        el.innerHTML = "";
        const svg = lucide.createElement(lucide[name]);
        svg.setAttribute("width", size);
        svg.setAttribute("height", size);
        el.appendChild(svg);
      }}
    />
  );
}

// A cinematic "film still" placeholder — gradient + grain + letterbox + play.
// Stands in for real footage in this recreation.
function Still({ tone = ["#101010", "#2a2a2a"], ratio = "16 / 9", hover = false, showPlay = true, children, style = {} }) {
  return (
    <div
      style={{
        position: "relative",
        aspectRatio: ratio,
        width: "100%",
        overflow: "hidden",
        background: `linear-gradient(135deg, ${tone[0]} 0%, ${tone[1]} 55%, ${tone[0]} 100%)`,
        ...style,
      }}
    >
      {/* directional key-light sheen */}
      <div style={{ position: "absolute", inset: 0,
        background: "radial-gradient(120% 90% at 75% 15%, rgba(255,255,255,0.10), rgba(255,255,255,0) 55%)" }} />
      {/* grain */}
      <div style={{ position: "absolute", inset: 0, opacity: 0.5, mixBlendMode: "overlay",
        backgroundImage: "url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='0.5'/%3E%3C/svg%3E\")" }} />
      {showPlay && (
        <div style={{
          position: "absolute", inset: 0, display: "flex", alignItems: "center", justifyContent: "center",
          opacity: hover ? 1 : 0.82, transition: "opacity 220ms cubic-bezier(0.22,1,0.36,1)",
        }}>
          <div style={{
            width: 64, height: 64, borderRadius: "50%",
            border: "2px solid rgba(255,255,255,0.85)", display: "flex", alignItems: "center", justifyContent: "center",
            background: "rgba(10,10,10,0.25)", backdropFilter: "blur(2px)",
            transform: hover ? "scale(1.08)" : "scale(1)", transition: "transform 220ms cubic-bezier(0.22,1,0.36,1)",
          }}>
            <Icon name="Play" size={24} style={{ color: "#fff", marginLeft: 3 }} />
          </div>
        </div>
      )}
      {children}
    </div>
  );
}

Object.assign(window, { Icon, Still });

// Viewport hook — tracks width so inline-styled components can go responsive.
// Returns { w, isMobile (<700), isTablet (<1000) }.
function useViewport() {
  const get = () => (typeof window !== "undefined" ? window.innerWidth : 1440);
  const [w, setW] = React.useState(get);
  React.useEffect(() => {
    const onResize = () => setW(get());
    window.addEventListener("resize", onResize);
    return () => window.removeEventListener("resize", onResize);
  }, []);
  return { w, isMobile: w < 700, isTablet: w < 1000 };
}

Object.assign(window, { useViewport });

// Scroll-triggered staggered reveal — matches the Selected Work grid.
// Returns { ref, shown }; fade from below over 0.3s, 100ms stagger via a shared clock ref.
function useReveal(revealClock) {
  const ref = React.useRef(null);
  const reduce = typeof window.matchMedia === "function" && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
  const [shown, setShown] = React.useState(reduce);
  React.useEffect(() => {
    if (reduce || !ref.current) { setShown(true); return; }
    const scroller = ref.current.closest("#prlx-scroll") || window;
    const target = scroller === window ? window : scroller;
    let raf = 0, done = false;
    const viewportBottom = () => scroller === window ? window.innerHeight : scroller.getBoundingClientRect().bottom;
    const cleanup = () => { target.removeEventListener("scroll", onScroll); window.removeEventListener("resize", onScroll); cancelAnimationFrame(raf); };
    const check = () => {
      if (done || !ref.current) return;
      const r = ref.current.getBoundingClientRect();
      if (r.top < viewportBottom() - 40) {
        done = true;
        const now = performance.now();
        const start = Math.max(now, (revealClock && revealClock.current) || now);
        if (revealClock) revealClock.current = start + 100; // 100ms stagger
        window.setTimeout(() => setShown(true), start - now);
        cleanup();
      }
    };
    const onScroll = () => { cancelAnimationFrame(raf); raf = requestAnimationFrame(check); };
    target.addEventListener("scroll", onScroll, { passive: true });
    window.addEventListener("resize", onScroll);
    check();
    return cleanup;
  }, [reduce, revealClock]);
  return { ref, shown };
}

Object.assign(window, { useReveal });
