/* Scroll-linked reveal: words go from dim to full ink color as the
   quote scrolls through the viewport, tracking scroll position directly
   rather than firing once on enter. */
function ScrollFillQuote({ text, className }) {
  const containerRef = React.useRef(null);
  const wordRefs = React.useRef([]);
  const words = React.useMemo(() => text.trim().split(/\s+/), [text]);

  const maxActiveRef = React.useRef(0);

  React.useEffect(() => {
    let raf = null;
    function update() {
      raf = null;
      const el = containerRef.current;
      if (!el) return;
      const rect = el.getBoundingClientRect();
      const vh = window.innerHeight || document.documentElement.clientHeight;
      // Reveal tracks the quote's own passage through the viewport: starts as
      // it enters at the bottom, finishes once its bottom edge reaches the
      // bottom of the viewport — i.e. fully revealed by the time the whole
      // quote has scrolled into view, not later.
      const start = vh;
      const span = rect.height * 1.8;
      let progress = (start - rect.top) / span;
      progress = Math.max(0, Math.min(1, progress));
      // Only allow the reveal to advance — scrolling back up shouldn't undo it.
      if (progress > maxActiveRef.current) maxActiveRef.current = progress;
      const p = maxActiveRef.current;
      // Soft multi-word band (rather than a hard cutoff) so the fill reads as
      // a visible sweep across the text instead of an instant snap. Word
      // positions are squeezed into [0, 1-band] so the last word still hits
      // full color exactly at p===1, instead of trailing off past it.
      const band = Math.max(1 / words.length, 0.18);
      wordRefs.current.forEach((node, i) => {
        if (!node) return;
        const wordPos = (i / words.length) * (1 - band);
        const wp = Math.max(0, Math.min(1, (p - wordPos) / band));
        node.style.color = 'rgba(10,17,36,' + (0.25 + 0.75 * wp) + ')';
      });
    }
    function onScroll() {
      if (raf == null) raf = requestAnimationFrame(update);
    }
    update();
    window.addEventListener('scroll', onScroll, { passive: true });
    window.addEventListener('resize', onScroll);
    return () => {
      window.removeEventListener('scroll', onScroll);
      window.removeEventListener('resize', onScroll);
      if (raf) cancelAnimationFrame(raf);
    };
  }, [words.length]);

  return (
    <blockquote ref={containerRef} className={className}>
      {words.map((w, i) => (
        <span key={i} ref={(node) => { wordRefs.current[i] = node; }} className="w-word">
          {w}{i < words.length - 1 ? ' ' : ''}
        </span>
      ))}
    </blockquote>
  );
}

function TestimonialRow() {
  return (
    <Reveal className="testimonial-row">
      <div className="testimonial-quote">
        <img
          className="testimonial-logo-img"
          src={window.__assets("logos/doordash.png")}
          alt="DoorDash"
        />
        <span className="tq-icon tq-open">
          <Icon name="quote" className="ic" />
        </span>
        <ScrollFillQuote
          className="testimonial-blockquote"
          text="Accounting automation works best when it starts with a deep understanding of the underlying systems, processes, and controls. As we bring more structure, auditability, and visibility to one of our largest accrual workflows, Mesh has been a great partner in helping us think through both the system design and automation layer. The Mesh team has felt like an extension of our team through this end-to-end redesign."
        />
        <div className="tq-close-row">
          <span className="tq-icon tq-close">
            <Icon name="quote" className="ic" />
          </span>
        </div>
        <div className="testimonial-credit">
          <div className="testimonial-name">— Christine Lafite, CPA</div>
          <div className="testimonial-role">Senior Manager, Accounting</div>
        </div>
      </div>
      <div className="testimonial-person">
        <span className="av-photo av-lg">
          <img
            src={window.__assets("christine-doordash.jpg")}
            alt="Christine Lafite"
            onError={function(e) {
              e.target.style.display = 'none';
              e.target.parentNode.setAttribute('data-initials', 'CL');
              e.target.parentNode.classList.add('av-fallback');
            }}
          />
        </span>
      </div>
    </Reveal>
  );
}

function Testimonial() {
  return (
    <section className="section testimonial-section">
      <div className="wrap">
        <TestimonialRow />
      </div>
    </section>
  );
}
