/* global React */
// Shared UI bits: icons, photo placeholder, halftone deco, reveal hook.

const { useEffect, useRef, useState } = React;

// ---- Icon: minimal inline SVGs (Lucide-style strokes) -----------
function Icon({ name, size = 20, stroke = 2, ...rest }) {
  const props = {
    width: size, height: size, viewBox: "0 0 24 24",
    fill: "none", stroke: "currentColor", strokeWidth: stroke,
    strokeLinecap: "round", strokeLinejoin: "round",
    ...rest,
  };
  switch (name) {
    case "arrow-right":
      return <svg {...props}><path d="M5 12h14M13 5l7 7-7 7"/></svg>;
    case "arrow-up-right":
      return <svg {...props}><path d="M7 17 17 7M8 7h9v9"/></svg>;
    case "arrow-down":
      return <svg {...props}><path d="M12 5v14M19 12l-7 7-7-7"/></svg>;
    case "play":
      return <svg {...props}><polygon points="6 4 20 12 6 20 6 4" fill="currentColor" stroke="none"/></svg>;
    case "calendar":
      return <svg {...props}><rect x="3" y="5" width="18" height="16" rx="2"/><path d="M16 3v4M8 3v4M3 11h18"/></svg>;
    case "map-pin":
      return <svg {...props}><path d="M12 22s8-7 8-12a8 8 0 1 0-16 0c0 5 8 12 8 12z"/><circle cx="12" cy="10" r="3"/></svg>;
    case "users":
      return <svg {...props}><path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M23 21v-2a4 4 0 0 0-3-3.87M16 3.13a4 4 0 0 1 0 7.75"/></svg>;
    case "sparkles":
      return <svg {...props}><path d="M12 3v4M12 17v4M3 12h4M17 12h4M5.6 5.6l2.8 2.8M15.6 15.6l2.8 2.8M5.6 18.4l2.8-2.8M15.6 8.4l2.8-2.8"/></svg>;
    case "globe":
      return <svg {...props}><circle cx="12" cy="12" r="9"/><path d="M3 12h18M12 3a14 14 0 0 1 0 18M12 3a14 14 0 0 0 0 18"/></svg>;
    case "check":
      return <svg {...props}><path d="M20 6 9 17l-5-5"/></svg>;
    case "mail":
      return <svg {...props}><rect x="2" y="4" width="20" height="16" rx="2"/><path d="m2 6 10 7 10-7"/></svg>;
    case "graduation":
      return <svg {...props}><path d="M2 9l10-5 10 5-10 5L2 9z"/><path d="M6 11v5a6 6 0 0 0 12 0v-5"/></svg>;
    case "megaphone":
      return <svg {...props}><path d="M3 11v2l13 4V7L3 11z"/><path d="M16 8a4 4 0 0 1 0 8"/></svg>;
    case "heart-hands":
      return <svg {...props}><path d="M12 21s-7-4.5-7-10a4 4 0 0 1 7-2.6A4 4 0 0 1 19 11c0 5.5-7 10-7 10z"/></svg>;
    case "spark":
      return <svg {...props}><path d="M12 2 14 9l7 2-7 2-2 7-2-7-7-2 7-2z"/></svg>;
    case "menu":
      return <svg {...props}><path d="M4 6h16M4 12h16M4 18h16"/></svg>;
    case "x":
      return <svg {...props}><path d="M18 6 6 18M6 6l12 12"/></svg>;
    case "chevron-right":
      return <svg {...props}><path d="m9 6 6 6-6 6"/></svg>;
    case "download":
      return <svg {...props}><path d="M12 3v12M7 10l5 5 5-5M3 21h18"/></svg>;
    case "external":
      return <svg {...props}><path d="M14 3h7v7M21 3l-9 9M19 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V7a2 2 0 0 1 2-2h6"/></svg>;
    case "scale":
      return <svg {...props}><path d="M12 3v18M5 8l-3 7h6L5 8zM19 8l-3 7h6l-3-7zM2 21h20"/></svg>;
    case "building":
      return <svg {...props}><rect x="4" y="3" width="16" height="18" rx="1"/><path d="M9 7h.01M15 7h.01M9 11h.01M15 11h.01M9 15h.01M15 15h.01M10 21v-4h4v4"/></svg>;
    case "rocket":
      return <svg {...props}><path d="M5 19c0-4 4-7 6-7 0 2-3 6-6 7zM12 15l-3-3a8 8 0 0 1 8-8h3v3a8 8 0 0 1-8 8z"/><circle cx="15" cy="9" r="1.2"/></svg>;
    default:
      return null;
  }
}

// ---- Photo placeholder (clearly marked) -------------------------
function PhotoPH({ caption, ratio = "4/3", style, tone = "purple", className, children, src, alt = "", position = "center" }) {
  const tones = {
    purple: { background: "linear-gradient(135deg, #2E1065 0%, #5B21B6 55%, #7C3AED 100%)" },
    blue:   { background: "linear-gradient(135deg, #1E3A8A 0%, #1E40AF 55%, #2563EB 100%)" },
    warm:   { background: "linear-gradient(135deg, #5b2a1a 0%, #b15a3a 55%, #d97757 100%)" },
    ink:    { background: "linear-gradient(135deg, #0E0E13 0%, #2F2F38 55%, #4A4A57 100%)" },
  };
  return (
    <div className={`photo-ph${src ? " has-photo" : ""}${className ? ` ${className}` : ""}`} style={{ aspectRatio: ratio, ...tones[tone], ...style }}>
      {src ? <img src={src} alt={alt} loading="lazy" style={{
        position: "absolute", inset: 0, width: "100%", height: "100%",
        objectFit: "cover", objectPosition: position,
      }}/> : null}
      {children}
      {caption ? <div className="ph-caption">{caption}</div> : null}
    </div>
  );
}

// ---- Decorative slashes ----------------------------------------
function Slashes({ size = 220, color = "rgba(167,139,250,0.22)", style, children = "//" }) {
  return (
    <span className="deco-slashes" style={{ fontSize: size, color, ...style }}>{children}</span>
  );
}

// ---- Reveal-on-scroll hook -------------------------------------
function useReveal() {
  const ref = useRef(null);
  useEffect(() => {
    const el = ref.current;
    if (!el) return;
    const targets = el.querySelectorAll(".reveal");
    if (targets.length === 0) return;
    const io = new IntersectionObserver((entries) => {
      entries.forEach((e) => {
        if (e.isIntersecting) {
          e.target.classList.add("in");
          io.unobserve(e.target);
        }
      });
    }, { threshold: 0.12, rootMargin: "0px 0px -40px 0px" });
    targets.forEach((t) => io.observe(t));
    return () => io.disconnect();
  });
  return ref;
}

// ---- Animated counter ------------------------------------------
function CountUp({ to, suffix = "", duration = 1400 }) {
  const ref = useRef(null);
  const [val, setVal] = useState(0);
  const started = useRef(false);
  useEffect(() => {
    const io = new IntersectionObserver((entries) => {
      entries.forEach((e) => {
        if (e.isIntersecting && !started.current) {
          started.current = true;
          const start = performance.now();
          const tick = (t) => {
            const p = Math.min(1, (t - start) / duration);
            const eased = 1 - Math.pow(1 - p, 3);
            setVal(Math.round(to * eased));
            if (p < 1) requestAnimationFrame(tick);
          };
          requestAnimationFrame(tick);
        }
      });
    }, { threshold: 0.3 });
    if (ref.current) io.observe(ref.current);
    return () => io.disconnect();
  }, [to, duration]);
  return <span ref={ref}>{val}{suffix}</span>;
}

// ---- Kinetic rotating word -------------------------------------
function KineticWord({ words, interval = 2200, color = "#A78BFA" }) {
  const [i, setI] = useState(0);
  useEffect(() => {
    const id = setInterval(() => setI((v) => (v + 1) % words.length), interval);
    return () => clearInterval(id);
  }, [words, interval]);
  const widest = words.reduce((a, b) => (a.length > b.length ? a : b), "");
  return (
    <span style={{ position: "relative", display: "inline-block", verticalAlign: "baseline", color }}>
      <span style={{ visibility: "hidden", whiteSpace: "nowrap" }}>{widest}</span>
      <span style={{ position: "absolute", inset: 0, overflow: "hidden", display: "inline-block" }}>
        {words.map((w, idx) => (
          <span key={w} style={{
            position: "absolute", inset: 0, whiteSpace: "nowrap",
            transform: idx === i ? "translateY(0)" : (idx === (i - 1 + words.length) % words.length ? "translateY(-100%)" : "translateY(100%)"),
            opacity: idx === i ? 1 : 0,
            transition: "transform 700ms cubic-bezier(0.22, 1, 0.36, 1), opacity 500ms cubic-bezier(0.22, 1, 0.36, 1)",
          }}>{w}</span>
        ))}
      </span>
    </span>
  );
}

// Make available to other scripts
Object.assign(window, { Icon, PhotoPH, Slashes, useReveal, CountUp, KineticWord });
