/* global React */
// MomOps Framework: chapter and block renderers, research notes, pull quotes.

// Split text and wrap query matches in <mark> for in-document search.
function hl(text, q) {
  if (!q || q.length < 2) return text;
  const parts = [];
  const re = new RegExp('(' + q.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') + ')', 'ig');
  let last = 0, m, i = 0;
  while ((m = re.exec(text)) !== null) {
    if (m.index > last) parts.push(text.slice(last, m.index));
    parts.push(React.createElement('mark', { className: 'fw-hit', key: i++ }, m[0]));
    last = m.index + m[0].length;
    if (m.index === re.lastIndex) re.lastIndex++;
  }
  if (last < text.length) parts.push(text.slice(last));
  return parts;
}

function LeadText({ lead, text, q }) {
  return (
    <>
      {lead ? <span className="lead">{hl(lead, q)} </span> : null}
      {hl(text, q)}
    </>
  );
}

function ListItem({ item, q }) {
  if (typeof item === 'string') return <li>{hl(item, q)}</li>;
  return <li><LeadText lead={item.lead} text={item.text} q={q} /></li>;
}

function ResearchNote({ label, text, q, forceOpen }) {
  return (
    <details className="fw-note" open={forceOpen || undefined}>
      <summary>
        <span className="fw-note-badge">Research</span>
        <span className="fw-note-label">{hl(label, q)}</span>
        <i className="fw-note-chev" data-lucide="chevron-down"></i>
      </summary>
      <div className="fw-note-body"><p>{hl(text, q)}</p></div>
    </details>
  );
}

function Block({ block, q, notesOpen }) {
  const b = block;
  switch (b.t) {
    case 'h3':   return <h3>{hl(b.text, q)}</h3>;
    case 'h4':   return <h4>{hl(b.text, q)}</h4>;
    case 'sub':  return <p className="fw-sub">{hl(b.text, q)}</p>;
    case 'p':    return <p><LeadText lead={b.lead} text={b.text} q={q} /></p>;
    case 'ul':   return <ul>{b.items.map((it, i) => <ListItem key={i} item={it} q={q} />)}</ul>;
    case 'ol':   return <ol>{b.items.map((it, i) => <ListItem key={i} item={it} q={q} />)}</ol>;
    case 'quote':return <blockquote className="fw-quote"><p>{hl(b.text, q)}</p>{b.cite ? <cite>{b.cite}</cite> : null}</blockquote>;
    case 'note': return <ResearchNote label={b.label} text={b.text} q={q} forceOpen={notesOpen} />;
    default:     return null;
  }
}

function Chapter({ chapter, index, q, notesOpen, focusMode, Interactive }) {
  const ref = React.useRef(null);
  React.useEffect(() => {
    const el = ref.current;
    if (!el) return;
    if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) { el.classList.add('is-in'); return; }
    const io = new IntersectionObserver((entries) => {
      entries.forEach((e) => { if (e.isIntersecting) { e.target.classList.add('is-in'); io.unobserve(e.target); } });
    }, { threshold: 0.08 });
    el.querySelectorAll('.fw-reveal').forEach((n) => io.observe(n));
    return () => io.disconnect();
  }, []);

  const num = String(index + 1).padStart(2, '0');
  return (
    <section className="fw-chapter" id={chapter.id} ref={ref} data-screen-label={'Ch ' + num}>
      <div className="fw-reveal">
        <div className="fw-chapter-head">
          <span className="fw-chapter-num">{num}</span>
          <span className="fw-chapter-kicker">{chapter.kicker}</span>
        </div>
        <h2>{hl(chapter.title, q)}</h2>
      </div>
      <div className="fw-prose">
        {chapter.blocks.map((b, i) => (
          <div className="fw-reveal" key={i}><Block block={b} q={q} notesOpen={notesOpen} /></div>
        ))}
      </div>
      {Interactive && !focusMode ? (
        <div className="fw-reveal"><Interactive /></div>
      ) : null}
    </section>
  );
}

Object.assign(window, { Chapter, Block, ResearchNote, hl });
