// challenges.jsx - "The Cost of Standing Still" diagnostic section.
// Monochrome stats with cited sources; one punchy line each; Violet Blue is
// reserved for the single forward action (the CTA bridge to Services).

const MONO = 'ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace';

const CHALLENGES = [
  {
    label: 'CASE-01 / TRANSFORMATION RISK',
    stat: 70, suffix: '%', fill: 70,
    caption: 'of digital transformations fail to deliver.',
    source: 'McKinsey',
    url: 'https://www.mckinsey.com/capabilities/transformation/our-insights/perspectives-on-transformation',
  },
  {
    label: 'CASE-02 / TECHNICAL DEBT',
    stat: 42, suffix: '%', fill: 42,
    caption: 'of developer time lost to tech debt and bad code.',
    source: 'Stripe · Developer Coefficient',
    url: 'https://stripe.com/files/reports/the-developer-coefficient.pdf',
  },
  {
    label: 'CASE-03 / VELOCITY GAP',
    stat: 5, suffix: '×', fill: 80,
    caption: 'faster revenue growth for high-velocity teams.',
    source: 'McKinsey · Developer Velocity',
    url: 'https://www.mckinsey.com/industries/technology-media-and-telecommunications/our-insights/developer-velocity-how-software-excellence-fuels-business-performance',
  },
];

// Robust in-view for Challenges via a CALLBACK ref (same proven path as Reveal):
// IntersectionObserver + timer-coalesced scroll/resize fallback (works when IO
// is throttled). Self-removes on reveal.
function chInView() {
  const [seen, setSeen] = React.useState(false);
  const cleanupRef = React.useRef(null);
  const set = React.useCallback((node) => {
    if (cleanupRef.current) { cleanupRef.current(); cleanupRef.current = null; }
    if (!node) return;
    let done = false, t;
    const reveal = () => { if (!done) { done = true; setSeen(true); if (cleanupRef.current) { cleanupRef.current(); cleanupRef.current = null; } } };
    const check = () => {
      const r = node.getBoundingClientRect();
      const vh = window.innerHeight || document.documentElement.clientHeight;
      if (r.top < vh * 0.9 && r.bottom > vh * 0.1) reveal();
    };
    const onScroll = () => { clearTimeout(t); t = setTimeout(check, 60); };
    const io = new IntersectionObserver(([e]) => { if (e.isIntersecting) reveal(); }, { threshold: 0.15 });
    io.observe(node);
    window.addEventListener('scroll', onScroll, { passive: true });
    window.addEventListener('resize', onScroll, { passive: true });
    setTimeout(check, 0);
    cleanupRef.current = () => { io.disconnect(); window.removeEventListener('scroll', onScroll); window.removeEventListener('resize', onScroll); clearTimeout(t); };
  }, []);
  return [set, seen];
}

function chCountUp(target, start, duration = 950, delay = 0) {
  const [val, setVal] = React.useState(0);
  React.useEffect(() => {
    if (!start) return;
    if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) { setVal(target); return; }
    let raf, t0;
    const tick = (now) => {
      if (!t0) t0 = now;
      const el = now - t0 - delay;
      if (el < 0) { raf = requestAnimationFrame(tick); return; }
      const p = Math.min(1, el / duration);
      const eased = 1 - Math.pow(1 - p, 3);
      setVal(eased * target);
      if (p < 1) raf = requestAnimationFrame(tick);
      else setVal(target);
    };
    raf = requestAnimationFrame(tick);
    return () => cancelAnimationFrame(raf);
  }, [start]);
  return val;
}

function Readout({ item, index, start }) {
  const delay = index * 140;
  const count = chCountUp(item.stat, start, 950, delay);
  const digits = String(item.stat).length;

  return (
    <div style={{
      paddingTop: 'clamp(16px, 2.4vh, 28px)',
      borderTop: '1px solid var(--hairline)',
      opacity: start ? 1 : 0,
      transform: start ? 'none' : 'translateY(22px)',
      transition: 'opacity 700ms cubic-bezier(0.16,1,0.3,1), transform 700ms cubic-bezier(0.16,1,0.3,1)',
      transitionDelay: `${delay}ms`,
    }}>
      {/* dossier case label */}
      <p style={{
        fontFamily: MONO, fontSize: 11.5, letterSpacing: '0.2em', fontWeight: 500,
        textTransform: 'uppercase', color: 'var(--fg-muted)', margin: 0,
      }}>{item.label}</p>

      {/* big monochrome stat */}
      <div style={{
        display: 'flex', alignItems: 'baseline', gap: 2,
        fontFamily: 'var(--font-display)', fontWeight: 650, color: 'var(--fg)',
        lineHeight: 1, marginTop: 'clamp(8px, 1.4vh, 16px)',
      }}>
        <span style={{ fontSize: 'clamp(2.4rem, 5.6vw, 4.25rem)', fontVariantNumeric: 'tabular-nums', minWidth: `${digits}ch`, textAlign: 'left' }}>
          {Math.round(count)}
        </span>
        <span style={{ fontSize: '0.42em', color: 'var(--fg-muted)' }}>{item.suffix}</span>
      </div>

      {/* monochrome magnitude rail - neutral, so colour never marks the problem */}
      <div style={{ height: 2, width: '100%', background: 'var(--hairline)', marginTop: 'clamp(10px, 1.6vh, 18px)', marginBottom: 'clamp(12px, 1.8vh, 20px)', overflow: 'hidden' }}>
        <div style={{
          height: '100%', background: 'color-mix(in srgb, var(--fg) 42%, transparent)', transformOrigin: 'left',
          transform: `scaleX(${start ? item.fill / 100 : 0})`,
          transition: `transform 950ms cubic-bezier(0.22,1,0.36,1) ${delay}ms`,
        }} />
      </div>

      {/* the one line that matters - full-contrast Raisin Black */}
      <p style={{ color: 'var(--fg)', fontSize: 'clamp(0.95rem, 1.3vw, 1.08rem)', lineHeight: 1.5, margin: 0, fontWeight: 600 }}>{item.caption}</p>

      {/* cited source - clickable, opens the original report in a new tab */}
      <a href={item.url} target="_blank" rel="noopener noreferrer" style={{
        fontFamily: MONO, color: 'var(--fg-muted)', fontSize: 12, letterSpacing: '0.04em',
        marginTop: 'clamp(8px, 1.2vh, 12px)', display: 'inline-flex', alignItems: 'center', gap: 5,
        textDecoration: 'none', borderBottom: '1px solid transparent',
        transition: 'color 200ms ease, border-color 200ms ease',
      }}
        onMouseEnter={(e) => { e.currentTarget.style.color = 'var(--accent)'; e.currentTarget.style.borderBottomColor = 'color-mix(in srgb, var(--accent) 45%, transparent)'; }}
        onMouseLeave={(e) => { e.currentTarget.style.color = 'var(--fg-muted)'; e.currentTarget.style.borderBottomColor = 'transparent'; }}
      >{item.source}
        <svg width="10" height="10" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="square" style={{ opacity: 0.8 }}><path d="M7 17L17 7M9 7h8v8" /></svg>
      </a>
    </div>
  );
}

function Challenges({ t }) {
  const [probeRef, inView] = chInView();

  const goToServices = (e) => {
    e.preventDefault();
    const el = document.getElementById('services');
    if (el) el.scrollIntoView({ behavior: 'smooth', block: 'start' });
  };

  return (
    <section id="challenges" data-screen-label="Challenges" aria-labelledby="ch-heading"
      style={{ position: 'relative', minHeight: 'calc(100svh - 72px)', display: 'flex', flexDirection: 'column', justifyContent: 'center',
        background: 'transparent', paddingBlock: 'clamp(24px, 3.5vh, 56px)' }}>
      <div ref={probeRef} style={{ maxWidth: 1140, margin: '0 auto', width: '100%', padding: '0 40px' }}>

        {/* header block - left aligned, editorial */}
        <div style={{ maxWidth: 680, marginBottom: 'clamp(28px, 4.5vh, 52px)' }}>
          <p style={{
            textTransform: 'uppercase', fontSize: 12, fontWeight: 500,
            letterSpacing: '0.34em', color: 'var(--accent)', margin: 0,
            opacity: inView ? 1 : 0, transform: inView ? 'none' : 'translateY(24px)',
            transition: 'opacity 800ms cubic-bezier(0.16,1,0.3,1), transform 800ms cubic-bezier(0.16,1,0.3,1)',
          }}>The Cost of Standing Still</p>

          <h2 id="ch-heading" style={{
            fontFamily: 'var(--font-display)', fontWeight: 600,
            fontSize: 'clamp(1.75rem, 3.8vw, 2.8rem)', lineHeight: 1.12,
            letterSpacing: '-0.02em', color: 'var(--fg)', margin: 'clamp(12px, 1.6vh, 18px) 0 0',
            opacity: inView ? 1 : 0, transform: inView ? 'none' : 'translateY(24px)',
            transition: 'opacity 800ms cubic-bezier(0.16,1,0.3,1) 100ms, transform 800ms cubic-bezier(0.16,1,0.3,1) 100ms',
          }}>
            Is your technology <span style={{ fontWeight: 650 }}>holding you back</span>?
          </h2>

          <p style={{
            fontSize: 'clamp(0.95rem, 1.3vw, 1.08rem)', lineHeight: 1.6,
            color: 'var(--fg-muted)', margin: 'clamp(12px, 1.6vh, 18px) 0 0', maxWidth: 540,
            opacity: inView ? 1 : 0, transform: inView ? 'none' : 'translateY(24px)',
            transition: 'opacity 800ms cubic-bezier(0.16,1,0.3,1) 170ms, transform 800ms cubic-bezier(0.16,1,0.3,1) 170ms',
          }}>
            These aren’t hypothetical problems. They’re draining your budget and momentum right now.
          </p>
        </div>

        {/* diagnostic grid */}
        <div className="challenges-grid">
          {CHALLENGES.map((item, i) => (
            <Readout key={item.label} item={item} index={i} start={inView} />
          ))}
        </div>

        {/* CTA bridge - the single forward action; the only Violet Blue in the section */}
        <div style={{
          marginTop: 'clamp(24px, 4vh, 48px)', display: 'flex', alignItems: 'center', gap: 20, flexWrap: 'wrap',
          opacity: inView ? 1 : 0, transform: inView ? 'none' : 'translateY(20px)',
          transition: 'opacity 800ms cubic-bezier(0.16,1,0.3,1) 520ms, transform 800ms cubic-bezier(0.16,1,0.3,1) 520ms',
        }}>
          <a href="#services" onClick={goToServices} className="gcta" style={{
            display: 'inline-flex', alignItems: 'center', gap: 10,
            padding: '15px 28px', borderRadius: 14, fontWeight: 600, fontSize: 15,
            background: 'var(--violet)', color: 'var(--platinum)', textDecoration: 'none',
            transition: 'transform 200ms ease, background 200ms ease, box-shadow 200ms ease',
          }}
            onMouseEnter={(e) => { e.currentTarget.style.transform = 'translateY(-2px)'; e.currentTarget.style.boxShadow = '0 14px 40px rgba(66,83,175,0.32)'; }}
            onMouseLeave={(e) => { e.currentTarget.style.transform = 'none'; e.currentTarget.style.boxShadow = 'none'; }}
          >See how we close the gap
            <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="square"><path d="M5 12h14M13 6l6 6-6 6" /></svg>
          </a>
          <span style={{ fontSize: 14, color: 'var(--fg-muted)' }}>This is exactly what we fix.</span>
        </div>
      </div>
    </section>
  );
}

window.Challenges = Challenges;
