// Hero — sideways 8: two paper wells laid horizontally, each a circle of 0s.
// Right orb sits in the same place and size as the original single well.
// Left orb spans under the copy on the left.
// The twist is in the middle of the page where they overlap.

function BrandInline({ color, weight = 600 }) {
  return (
    <span className="bn" style={{ fontWeight: weight }}>
      <span style={{ color: 'var(--accent)' }}>8</span>
      <span style={{ color: color || '#FFFFFF' }}>/</span>
      <span style={{ color: 'var(--accent)' }}>0</span>
    </span>
  );
}

// String of 8s long enough to cover a circular path with no visible seam.
// (8s on the rings; the centerpiece tagline is the 0. Fractal of the brand:
//  the 8 surface, the 0 void.)
function fillRingEights(radius, fontSize) {
  const circumference = 2 * Math.PI * radius;
  const charWidth = fontSize * 0.55;
  const count = Math.ceil(circumference / charWidth) + 12;
  return '8'.repeat(count);
}

// One orb of the sideways-8. Same paper-well depth treatment as the
// original well: outer / mid / inner concentric paper layers + rings of 8s.
// The brand fractal: rings of 8 (the surface) framing a 0 (the void).
function HeroOrb({ side, hasCenterContent }) {
  const rings = [
    // Outer surface
    { r: 230, size: 11, opacity: 0.09 },
    { r: 245, size: 11, opacity: 0.11 },
    { r: 260, size: 12, opacity: 0.10 },
    { r: 275, size: 12, opacity: 0.08 },
    // Middle surface
    { r: 135, size: 10, opacity: 0.13 },
    { r: 148, size: 10, opacity: 0.14 },
    { r: 161, size: 10, opacity: 0.16 },
    { r: 174, size: 10, opacity: 0.15 },
    { r: 187, size: 10, opacity: 0.14 },
    { r: 200, size: 10, opacity: 0.12 },
    { r: 213, size: 11, opacity: 0.10 },
    // Inner surface — near the rim of the void
    { r: 88,  size: 9,  opacity: 0.20 },
    { r: 101, size: 9,  opacity: 0.18 },
    { r: 114, size: 9,  opacity: 0.15 },
  ];
  const pathId = (i) => `orb-${side}-ring-${i}`;
  return (
    <div className={`orb orb-${side}`}>
      <div className="well well-outer">
        <div className="well well-mid">
          <div className="well well-inner"/>
        </div>
      </div>

      <svg className="well-svg" viewBox="-290 -290 580 580">
        <defs>
          {rings.map((r, i) => (
            <path key={i}
              id={pathId(i)}
              d={`M ${-r.r},0 a ${r.r},${r.r} 0 1,1 ${r.r*2},0 a ${r.r},${r.r} 0 1,1 ${-r.r*2},0`}
              fill="none"/>
          ))}
        </defs>
        {rings.map((r, i) => (
          <text key={i} className="ring-text"
            fontSize={r.size}
            fill={`rgba(199,245,221,${r.opacity})`}
            textLength={2 * Math.PI * r.r}
            lengthAdjust="spacingAndGlyphs">
            <textPath href={`#${pathId(i)}`} startOffset="0">
              {fillRingEights(r.r, r.size)}
            </textPath>
          </text>
        ))}
      </svg>

      {hasCenterContent && (
        <div className="emerging-mark">
          <p className="center-text">
            <Typewriter
              text={"Infinite connectivity,\nzero friction."}
              delay={700}
              speed={48}
              suffix={<sup className="tm">™</sup>}
            />
          </p>
        </div>
      )}
    </div>
  );
}

// Typewriter — types `text` once after a delay, ends with optional suffix.
// `trigger`:
//   - 'load'      — start after `delay` ms (default)
//   - 'visible'   — start when the element scrolls into view (IntersectionObserver)
// Page-life singleton: once it finishes for a given text, a session flag
// stops it from replaying if the component remounts.
const TYPED = (typeof window !== 'undefined') ? (window.__typed = window.__typed || {}) : {};
function Typewriter({ text, delay = 400, speed = 40, suffix, className, trigger = 'load' }) {
  const already = !!TYPED[text];
  const [shown, setShown] = React.useState(already ? text : '');
  const [done, setDone]   = React.useState(already);
  const [armed, setArmed] = React.useState(trigger === 'load' || already);
  const ref = React.useRef(null);

  // For trigger='visible', arm once the node is in view.
  // Belt-and-suspenders: IntersectionObserver is unreliable in some iframed
  // preview contexts (callbacks never fire). Pair it with a scroll listener
  // that does the bounding-rect check directly. Whichever wins, arms first.
  React.useEffect(() => {
    if (trigger !== 'visible' || armed) return;
    const node = ref.current;
    if (!node) return;

    let cancelled = false;
    const arm = () => { if (!cancelled) { cancelled = true; setArmed(true); } };

    // 1) IntersectionObserver (preferred — fires once on entry).
    let io;
    try {
      io = new IntersectionObserver((entries) => {
        for (const e of entries) {
          if (e.isIntersecting) { arm(); io && io.disconnect(); break; }
        }
      }, { rootMargin: '0px 0px -10% 0px' });
      io.observe(node);
    } catch (_) { /* IO not available — fallback handles it */ }

    // 2) Scroll/resize fallback — check every frame the user scrolls.
    const check = () => {
      if (cancelled) return;
      const r = node.getBoundingClientRect();
      const vh = window.innerHeight || document.documentElement.clientHeight;
      if (r.top < vh * 0.92 && r.bottom > 0) {
        arm();
        cleanup();
      }
    };
    const cleanup = () => {
      window.removeEventListener('scroll', check, true);
      window.removeEventListener('resize', check);
      io && io.disconnect();
    };
    window.addEventListener('scroll', check, { passive: true, capture: true });
    window.addEventListener('resize', check);
    // Initial check (in case it's already in view at mount).
    requestAnimationFrame(check);

    return cleanup;
  }, [trigger, armed]);

  // Once armed, run the typewriter — UNLESS this is a `trigger='visible'`
  // instance, in which case we snap to final state. Background iframes /
  // throttled preview contexts can starve setInterval and rAF (we've been
  // burned), so on-scroll typewriters render the full text the moment they
  // arm. The hero's `trigger='load'` typewriter still animates as usual.
  React.useEffect(() => {
    if (!armed || already) return;
    if (trigger === 'visible') {
      setShown(text);
      TYPED[text] = true;
      setDone(true);
      return;
    }
    let i = 0, tickTimer;
    const startTimer = setTimeout(() => {
      tickTimer = setInterval(() => {
        i++;
        setShown(text.slice(0, i));
        if (i >= text.length) {
          clearInterval(tickTimer);
          TYPED[text] = true;
          setDone(true);
        }
      }, speed);
    }, delay);
    return () => { clearTimeout(startTimer); if (tickTimer) clearInterval(tickTimer); };
  }, [armed, text, delay, speed, already, trigger]);

  return (
    <span ref={ref} className={className} style={{ display: 'inline-block', minWidth: '1ch', minHeight: '1em' }}>
      {shown}
      {armed && !done && <span className="type-cursor" aria-hidden="true">▌</span>}
      {done && suffix}
    </span>
  );
}

function HeroV2() {
  return (
    <section className="hero-paper-section hero-sideways">
      {/* Sideways-8 stage — two orbs absolutely positioned. */}
      <div className="sideways-stage">
        <div className="sideways-stage-inner">
          <HeroOrb side="left"  hasCenterContent={false}/>
          <HeroOrb side="right" hasCenterContent={true}/>
        </div>
      </div>

      {/* Copy overlay — sits on top of the left orb. */}
      <div className="container hero-content-overlay">
        <div className="hero-copy">
          <span className="eyebrow-chip" style={{ alignSelf: 'flex-start' }}>
            Insurtech Agentic Data Layer
          </span>

          <h1 style={{
            fontSize: 'clamp(36px, 4vw, 60px)',
            lineHeight: 1.05,
            fontWeight: 600,
            letterSpacing: '-0.02em',
            margin: 0,
            color: '#FFFFFF',
            maxWidth: 540,
          }}>
            All employer data.<br/>
            Any carrier or TPA.<br/>
            <span style={{ color: 'var(--accent)' }}>One agentic layer.</span>
          </h1>

          <p style={{
            fontSize: 18, lineHeight: 1.6,
            color: 'rgba(232,243,236,0.74)',
            margin: 0, maxWidth: 520, fontWeight: 400,
          }}>
            <BrandInline/> is the integration layer that boosts every team it
            touches — pre-sales, implementation, ops, and well beyond.
          </p>

          <div style={{ display: 'flex', gap: 24, marginTop: 12, alignItems: 'center' }}>
            <a href="https://calendar.app.google/9eoXfoSh692Xr7ks9" target="_blank" rel="noopener" className="btn btn-soft">Book a demo</a>
            <a href="#how" className="btn btn-link">How <BrandInline/> boosts your team</a>
          </div>
        </div>
      </div>
    </section>
  );
}

window.HeroV2 = HeroV2;
window.BrandInline = BrandInline;
window.Typewriter = Typewriter;
