/* utils.jsx — shared helpers exposed on window */

const fmt = {
  pct: (v, d=0) => `${v.toFixed(d)}%`,
  m: (v, d=1) => `$${v.toFixed(d)}M`,
  b: (v, d=2) => `$${v.toFixed(d)}B`,
  num: (v, d=0) => v.toLocaleString('en-NZ', { maximumFractionDigits: d, minimumFractionDigits: d }),
};

const lerp = (a, b, t) => a + (b - a) * t;
const clamp = (v, lo, hi) => Math.max(lo, Math.min(hi, v));
const inv = (v, lo, hi) => (v - lo) / (hi - lo);

// build a smooth path through a list of {x, y} points (Catmull-Rom-ish)
function smoothPath(pts) {
  if (pts.length < 2) return '';
  let d = `M ${pts[0].x} ${pts[0].y}`;
  for (let i = 0; i < pts.length - 1; i++) {
    const p0 = pts[i - 1] || pts[i];
    const p1 = pts[i];
    const p2 = pts[i + 1];
    const p3 = pts[i + 2] || p2;
    const c1x = p1.x + (p2.x - p0.x) / 6;
    const c1y = p1.y + (p2.y - p0.y) / 6;
    const c2x = p2.x - (p3.x - p1.x) / 6;
    const c2y = p2.y - (p3.y - p1.y) / 6;
    d += ` C ${c1x.toFixed(2)} ${c1y.toFixed(2)}, ${c2x.toFixed(2)} ${c2y.toFixed(2)}, ${p2.x} ${p2.y}`;
  }
  return d;
}

// reusable stat / number block
function Stat({ value, sub, color, big }) {
  return (
    <div>
      <div className={`bignum ${color || ''}`} style={big ? { fontSize: 80 } : null}>{value}</div>
      <div className="bignum-sub">{sub}</div>
    </div>
  );
}

// section header with eyebrow
function SectionHeader({ num, tag, title, lede, id }) {
  return (
    <div id={id}>
      <div className="section-tag">
        <span className="num">{num}</span>
        <span>{tag}</span>
        <span className="rule" />
      </div>
      <h2>{title}</h2>
      {lede ? <p className="lede">{lede}</p> : null}
    </div>
  );
}

// accessible toggle
function Toggle({ on, onChange, label }) {
  return (
    <button
      onClick={() => onChange(!on)}
      style={{
        display: 'inline-flex', alignItems: 'center', gap: 10,
        background: 'transparent', border: 'none', cursor: 'pointer',
        padding: 0, font: 'inherit', color: 'var(--ink)',
      }}
    >
      <span style={{
        width: 32, height: 18, borderRadius: 999,
        background: on ? 'var(--ink)' : '#d4cfc1',
        position: 'relative', transition: 'background .15s',
      }}>
        <span style={{
          position: 'absolute', top: 2, left: on ? 16 : 2,
          width: 14, height: 14, borderRadius: '50%',
          background: 'var(--bg-card)', transition: 'left .15s',
        }} />
      </span>
      <span style={{ fontSize: 13 }}>{label}</span>
    </button>
  );
}

// IntersectionObserver hook for nav highlight
function useActiveSection(ids) {
  const [active, setActive] = React.useState(ids[0]);
  React.useEffect(() => {
    const handler = () => {
      const y = window.scrollY + 120;
      let cur = ids[0];
      for (const id of ids) {
        const el = document.getElementById(id);
        if (el && el.offsetTop <= y) cur = id;
      }
      setActive(cur);
    };
    window.addEventListener('scroll', handler, { passive: true });
    handler();
    return () => window.removeEventListener('scroll', handler);
  }, [ids.join(',')]);
  return active;
}

Object.assign(window, { fmt, lerp, clamp, inv, smoothPath, Stat, SectionHeader, Toggle, useActiveSection });
