// Primitives: small building blocks shared across sections.
const { useEffect, useRef, useState, useMemo, createContext, useContext } = React;

// IntersectionObserver-based reveal
function useReveal() {
  const ref = useRef(null);
  useEffect(() => {
    const el = ref.current;
    if (!el) return;
    let raf1, raf2, t;
    const show = () => {
      // Double rAF so the initial opacity:0 frame paints before transition begins.
      raf1 = requestAnimationFrame(() => {
        raf2 = requestAnimationFrame(() => { el.classList.add('in'); });
      });
    };
    const rect = el.getBoundingClientRect();
    const vh = window.innerHeight || document.documentElement.clientHeight;
    if (rect.top < vh * 0.95 && rect.bottom > 0) {
      show();
      return () => { cancelAnimationFrame(raf1); cancelAnimationFrame(raf2); };
    }
    const io = new IntersectionObserver((entries) => {
      entries.forEach(e => { if (e.isIntersecting) { show(); io.unobserve(e.target); } });
    }, { threshold: 0.08 });
    io.observe(el);
    t = setTimeout(() => { show(); }, 1500);
    return () => { io.disconnect(); clearTimeout(t); cancelAnimationFrame(raf1); cancelAnimationFrame(raf2); };
  }, []);
  return ref;
}

function Reveal({ children, as: As = 'div', delay = 0, className = '', style = {}, ...rest }) {
  const ref = useRef(null);
  const [animate, setAnimate] = useState(null);
  useEffect(() => {
    const el = ref.current;
    if (!el) return;
    const rect = el.getBoundingClientRect();
    const vh = window.innerHeight || document.documentElement.clientHeight;
    if (rect.top < vh * 0.95 && rect.bottom > 0) { setAnimate(false); return; }
    setAnimate(true);
    const io = new IntersectionObserver((entries) => {
      entries.forEach(e => { if (e.isIntersecting) { el.classList.add('in'); io.unobserve(e.target); } });
    }, { threshold: 0.08 });
    io.observe(el);
    const t = setTimeout(() => { el.classList.add('in'); }, 2000);
    return () => { io.disconnect(); clearTimeout(t); };
  }, []);
  const cls = animate === true ? `reveal ${className}` : className;
  return (
    <As ref={ref} className={cls} style={{ transitionDelay: `${delay}ms`, ...style }} {...rest}>
      {children}
    </As>
  );
}

function SectionEyebrow({ num, label }) {
  return (
    <div className="section-eyebrow">
      <span className="num">{num}</span>
      <span>{label}</span>
      <span className="rule" />
    </div>
  );
}

function ArrowRight({ size = 14 }) {
  return (
    <svg className="arrow" width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
      <path d="M5 12h14" />
      <path d="m12 5 7 7-7 7" />
    </svg>
  );
}

function Logomark({ size = 28, color }) {
  // BetterPipe lockup — a "B" formed by a vertical pipe with two arcs that double as a flow icon.
  // Distinctive but simple: pipe + two arrows showing signal -> outreach.
  const c = color || 'currentColor';
  return (
    <svg width={size} height={size} viewBox="0 0 32 32" fill="none" aria-label="BetterPipe">
      <rect x="3" y="3" width="3.5" height="26" rx="1.5" fill={c} />
      <path d="M9 7 H17 a6 6 0 0 1 6 6 v0 a6 6 0 0 1 -6 6 H9" stroke={c} strokeWidth="3.2" fill="none" strokeLinecap="round" />
      <circle cx="22" cy="24" r="2.5" fill="var(--signal)" />
    </svg>
  );
}

function Wordmark() {
  return (
    <a href="#top" style={{ display: 'inline-flex', alignItems: 'center', gap: 10, color: 'var(--fg)' }}>
      <Logomark size={22} />
      <span style={{ fontFamily: 'var(--font-display)', fontWeight: 600, fontSize: 17, letterSpacing: '-0.02em' }}>
        Better<span style={{ color: 'var(--signal)', fontStyle: 'italic', fontFamily: 'var(--font-italic)', fontWeight: 400, marginLeft: 2 }}>pipe</span>
      </span>
    </a>
  );
}

// Tag/chip
function Chip({ children, color = 'default', size = 'md', style = {} }) {
  const colors = {
    default: { bg: 'var(--bg-3)', fg: 'var(--fg)', bd: 'var(--rule-strong)' },
    signal: { bg: 'color-mix(in srgb, var(--signal) 18%, transparent)', fg: 'var(--signal)', bd: 'color-mix(in srgb, var(--signal) 35%, transparent)' },
    amber: { bg: 'color-mix(in srgb, var(--amber) 18%, transparent)', fg: 'var(--amber)', bd: 'color-mix(in srgb, var(--amber) 35%, transparent)' },
    alarm: { bg: 'color-mix(in srgb, var(--alarm) 18%, transparent)', fg: 'var(--alarm)', bd: 'color-mix(in srgb, var(--alarm) 35%, transparent)' },
    ghost: { bg: 'transparent', fg: 'var(--fg-mute)', bd: 'var(--rule)' },
  };
  const c = colors[color] || colors.default;
  const padding = size === 'sm' ? '4px 8px' : '5px 10px';
  const fontSize = size === 'sm' ? 10 : 11;
  return (
    <span style={{
      display: 'inline-flex', alignItems: 'center', gap: 6,
      padding, fontSize, fontFamily: 'var(--font-mono)',
      letterSpacing: '0.08em', textTransform: 'uppercase', fontWeight: 500,
      background: c.bg, color: c.fg, border: `1px solid ${c.bd}`,
      borderRadius: 999, ...style,
    }}>{children}</span>
  );
}

// HeroContext for hero copy
const HeroContext = createContext(null);

Object.assign(window, {
  useReveal, Reveal, SectionEyebrow, ArrowRight, Logomark, Wordmark, Chip, HeroContext,
});
