/* global React, window */
const { useEffect, useRef, useState } = React;

// ============ icons (inline SVG, stroke-based) ============
const Icon = ({ name, size = 20, stroke = 1.6 }) => {
  const p = { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: stroke, strokeLinecap: "round", strokeLinejoin: "round" };
  switch (name) {
    case "palette":   return <svg {...p}><circle cx="13.5" cy="6.5" r="1"/><circle cx="17.5" cy="10.5" r="1"/><circle cx="8.5" cy="7.5" r="1"/><circle cx="6.5" cy="12.5" r="1"/><path d="M12 22a10 10 0 1 1 10-10c0 3-2 4-4 4h-2a2 2 0 0 0-2 2 3 3 0 0 1-2 4z"/></svg>;
    case "pen":       return <svg {...p}><path d="M12 19l7-7 3 3-7 7-3-3z"/><path d="M18 13l-1.5-7.5L2 2l3.5 14.5L13 18l5-5z"/><path d="M2 2l7.586 7.586"/><circle cx="11" cy="11" r="2"/></svg>;
    case "megaphone": return <svg {...p}><path d="M3 11l18-5v12L3 14v-3z"/><path d="M11.6 16.8a3 3 0 1 1-5.8-1.6"/></svg>;
    case "compass":   return <svg {...p}><circle cx="12" cy="12" r="10"/><polygon points="16.24 7.76 14.12 14.12 7.76 16.24 9.88 9.88 16.24 7.76"/></svg>;
    case "target":    return <svg {...p}><circle cx="12" cy="12" r="10"/><circle cx="12" cy="12" r="6"/><circle cx="12" cy="12" r="2"/></svg>;
    case "crown":     return <svg {...p}><path d="M2 20h20"/><path d="M2 8l5 4 5-8 5 8 5-4v10H2z"/></svg>;
    case "message":   return <svg {...p}><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/></svg>;
    case "settings":  return <svg {...p}><circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 1 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 1 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 1 1-2.83-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 1 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 1 1 2.83-2.83l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 1 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 1 1 2.83 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 1 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z"/></svg>;
    case "arrow":     return <svg {...p}><line x1="5" y1="12" x2="19" y2="12"/><polyline points="12 5 19 12 12 19"/></svg>;
    case "arrow-ur":  return <svg {...p}><line x1="7" y1="17" x2="17" y2="7"/><polyline points="7 7 17 7 17 17"/></svg>;
    case "plus":      return <svg {...p}><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></svg>;
    case "whatsapp":  return <svg {...p}><path d="M20.52 3.48A11.82 11.82 0 0 0 12.05 0C5.5 0 .2 5.28.2 11.8c0 2.08.55 4.11 1.58 5.9L0 24l6.48-1.7a11.9 11.9 0 0 0 5.57 1.42h.01c6.56 0 11.86-5.28 11.86-11.8 0-3.15-1.23-6.1-3.4-8.44zM12.05 21.6h-.01a9.73 9.73 0 0 1-4.96-1.36l-.35-.21-3.85 1 1.03-3.74-.23-.38a9.63 9.63 0 0 1-1.5-5.12c0-5.36 4.39-9.72 9.78-9.72 2.62 0 5.07 1.01 6.92 2.84a9.61 9.61 0 0 1 2.87 6.88c0 5.37-4.4 9.81-9.7 9.81z" fill="currentColor" stroke="none"/><path d="M17.4 14.35c-.29-.14-1.72-.84-1.98-.94-.27-.1-.46-.14-.65.14-.2.28-.75.94-.92 1.13-.17.19-.34.21-.63.07-.29-.14-1.23-.45-2.33-1.43a8.66 8.66 0 0 1-1.62-2c-.17-.28-.02-.44.12-.58.13-.13.29-.34.43-.5.14-.17.19-.29.29-.47.1-.19.05-.35-.02-.5-.07-.14-.65-1.57-.89-2.15-.24-.57-.48-.49-.65-.5l-.56-.01a1.07 1.07 0 0 0-.77.36c-.27.28-1.02 1-1.02 2.44s1.05 2.83 1.19 3.02c.14.19 2.06 3.15 5 4.42.7.3 1.24.48 1.66.62.7.22 1.34.19 1.84.12.56-.08 1.72-.7 1.97-1.38.24-.68.24-1.25.17-1.37-.07-.12-.26-.19-.55-.33z" fill="currentColor" stroke="none"/></svg>;
    case "instagram": return <svg {...p}><rect x="2" y="2" width="20" height="20" rx="5"/><path d="M16 11.37A4 4 0 1 1 12.63 8 4 4 0 0 1 16 11.37z"/><line x1="17.5" y1="6.5" x2="17.51" y2="6.5"/></svg>;
    default: return null;
  }
};

// ============ reveal-on-scroll hook ============
const useReveal = () => {
  useEffect(() => {
    const io = new IntersectionObserver((entries) => {
      entries.forEach((e) => { if (e.isIntersecting) { e.target.classList.add("in"); io.unobserve(e.target); } });
    }, { rootMargin: "0px 0px -8% 0px" });

    const observed = new WeakSet();
    const scan = () => {
      document.querySelectorAll(".reveal").forEach((el) => {
        if (observed.has(el)) return;
        observed.add(el);
        // if already in viewport on first paint, mark it immediately so
        // above-the-fold content never waits for a scroll event
        const r = el.getBoundingClientRect();
        const vh = window.innerHeight || document.documentElement.clientHeight;
        if (r.top < vh * 0.95) {
          el.classList.add("in");
        } else {
          io.observe(el);
        }
      });
    };

    // section divider lines
    const sio = new IntersectionObserver((entries) => {
      entries.forEach((e) => { if (e.isIntersecting) { e.target.classList.add("line-in"); sio.unobserve(e.target); } });
    }, { rootMargin: "0px 0px -10% 0px" });
    document.querySelectorAll(".section").forEach((s) => sio.observe(s));

    // run a few times to catch components that mount after useEffect fires
    scan();
    const t1 = setTimeout(scan, 50);
    const t2 = setTimeout(scan, 200);
    const t3 = setTimeout(scan, 600);

    // and watch for future DOM additions
    const mo = new MutationObserver(scan);
    mo.observe(document.body, { childList: true, subtree: true });

    return () => { io.disconnect(); sio.disconnect(); mo.disconnect(); clearTimeout(t1); clearTimeout(t2); clearTimeout(t3); };
  }, []);
};

// ============ cursor glow ============
const CursorGlow = () => {
  const ref = useRef(null);
  useEffect(() => {
    const INTERACTIVE = "a:not(.nav-logo):not(.nav-link):not(.nav-cta),button:not(.nav-burger),[role='button'],.team-card,.bento-card,.case-row,.gem-phase,.faq-item";
    const move = (e) => {
      if (!ref.current) return;
      ref.current.style.transform = `translate(${e.clientX}px, ${e.clientY}px) translate(-50%, -50%)`;
    };
    const over = (e) => {
      if (!ref.current) return;
      if (e.target.closest(INTERACTIVE)) {
        ref.current.style.width = "180px";
        ref.current.style.height = "180px";
        ref.current.style.opacity = ".18";
        ref.current.style.mixBlendMode = "screen";
      }
    };
    const out = (e) => {
      if (!ref.current) return;
      if (e.target.closest(INTERACTIVE)) {
        ref.current.style.width = "";
        ref.current.style.height = "";
        ref.current.style.opacity = "";
        ref.current.style.mixBlendMode = "";
      }
    };
    window.addEventListener("pointermove", move);
    document.addEventListener("pointerover", over);
    document.addEventListener("pointerout", out);
    return () => {
      window.removeEventListener("pointermove", move);
      document.removeEventListener("pointerover", over);
      document.removeEventListener("pointerout", out);
    };
  }, []);
  return <div ref={ref} className="cursor-glow" aria-hidden />;
};

// ============ count-up ============
const CountUp = ({ to, prefix = "", suffix = "", duration = 1200 }) => {
  const [val, setVal] = useState(0);
  const ref = useRef(null);
  useEffect(() => {
    const el = ref.current;
    if (!el) return;
    const io = new IntersectionObserver(([entry]) => {
      if (!entry.isIntersecting) return;
      io.disconnect();
      const start = performance.now();
      const tick = (now) => {
        const p = Math.min((now - start) / duration, 1);
        const ease = 1 - Math.pow(1 - p, 3);
        setVal(Math.round(ease * to));
        if (p < 1) requestAnimationFrame(tick);
      };
      requestAnimationFrame(tick);
    }, { threshold: 0.5 });
    io.observe(el);
    return () => io.disconnect();
  }, [to, duration]);
  return <span ref={ref}>{prefix}{val}{suffix}</span>;
};

// ============ floating WhatsApp ============
const FloatingWhatsApp = () => (
  <a className="fab" href={window.DATA.WHATSAPP_URL} target="_blank" rel="noreferrer" aria-label="WhatsApp">
    <Icon name="whatsapp" size={26} />
  </a>
);

// ============ section header ============
const SectionHead = ({ tag, title, kicker, right }) => (
  <div className="section-head">
    <div className="reveal">
      {tag && <div className="eyebrow" style={{ marginBottom: 16 }}>{tag}</div>}
      <h2 style={{ textWrap: "balance" }}>{title}</h2>
    </div>
    {right && <div className="reveal reveal-d1">{right}</div>}
    {!right && kicker && <div className="reveal reveal-d1" style={{ color: "var(--fg-muted)", fontSize: 16, lineHeight: 1.6, maxWidth: "52ch" }}>{kicker}</div>}
  </div>
);

Object.assign(window, { Icon, useReveal, CursorGlow, CountUp, FloatingWhatsApp, SectionHead });
