/* global React, window */
// ─────────────────────────────────────────────────────────────
// AttributedSynthesis + AttributedParagraph + richifyWithCitations
// Lifted from ref/mastermind-v2/components/response-ui.jsx:221–340
//
// Departures from v2 source:
//   • MODELS_BY_ID + ModelChip can be passed as props OR read from window,
//     matching the ThinkingTrace convention.
//   • renderCiteMarkup + richifyWithCitations exported alongside so other
//     components (CouncilDebate, future Verdict) can reuse citation rendering.
//   • The paragraph lead-color is memoized per paragraph (segments don't
//     change identity during a message lifetime; cheap win).
//   • Added `density: 'compact' | 'regular' | 'spacious'` (was just two).
//   • Dangerous-HTML surface stays the same; citations sanitize the `title`
//     attribute only.
// ─────────────────────────────────────────────────────────────

const AS_FONT = '"Inter", -apple-system, BlinkMacSystemFont, sans-serif';

// ── cite markup ──────────────────────────────────────────────
function renderCiteMarkup(c) {
  const color = c.kind === 'web'    ? '#0088C8'
             : c.kind === 'doc'    ? '#C01A7E'
             : c.kind === 'memory' ? '#6A3BD2'
             :                       'rgba(0,0,0,0.6)';
  const bg    = c.kind === 'web'    ? 'rgba(0, 212, 255, 0.12)'
             : c.kind === 'doc'    ? 'rgba(255, 45, 180, 0.10)'
             : c.kind === 'memory' ? 'rgba(155, 92, 255, 0.10)'
             :                       'rgba(0,0,0,0.05)';
  const label = c.short || c.title;
  const safeTitle = (c.title || '').replace(/"/g, '&quot;');
  return `<sup data-cite="${c.id}" title="${safeTitle}"
    style="display:inline-flex;align-items:center;gap:3px;padding:0 5px 0 4px;margin:0 1px;border-radius:4px;
           background:${bg};color:${color};font-size:10px;font-weight:600;letter-spacing:0;cursor:pointer;
           vertical-align:2px;text-decoration:none;line-height:14px;height:15px;">
    <span style="width:8px;height:8px;border-radius:2px;background:${color};opacity:.7"></span>${label}</sup>`;
}

function richifyWithCitations(s, segCitations, allCitations) {
  let html = s
    .replace(/\*\*(.+?)\*\*/g, '<b style="color:#000;font-weight:600">$1</b>')
    .replace(/`([^`]+)`/g, '<code style="background:rgba(0,0,0,0.05);padding:1px 5px;border-radius:4px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:0.92em">$1</code>');

  // inline cite markers [[cite:ID]]
  html = html.replace(/\[\[cite:([^\]]+)\]\]/g, (_, id) => {
    const c = allCitations.find(x => x.id === id);
    return c ? renderCiteMarkup(c) : '';
  });

  // appended per-segment citations
  if (segCitations && segCitations.length) {
    const extras = segCitations
      .map(id => allCitations.find(c => c.id === id))
      .filter(Boolean)
      .map(renderCiteMarkup)
      .join('');
    html = html + extras;
  }
  return html;
}

// ── AttributedSynthesis ──────────────────────────────────────
function AttributedSynthesis({
  paragraphs,
  density = 'regular',
  citations = [],
  onPeek,
  MODELS_BY_ID,
  hideEdges = false,
}) {
  MODELS_BY_ID = MODELS_BY_ID || window.MODELS_BY_ID;
  const [hoveredId, setHoveredId] = React.useState(null);

  const fontSize  = density === 'compact'  ? 14
                  : density === 'spacious' ? 16.5
                  :                          15.5;
  const paraGap   = density === 'compact'  ? 8 : density === 'spacious' ? 14 : 10;

  // delegate cite clicks
  const rootRef = React.useRef(null);
  React.useEffect(() => {
    const el = rootRef.current;
    if (!el || !onPeek) return;
    const handler = (e) => {
      const sup = e.target.closest('[data-cite]');
      if (!sup) return;
      const id = sup.getAttribute('data-cite');
      const cite = citations.find(c => c.id === id);
      if (cite) onPeek(cite);
    };
    el.addEventListener('click', handler);
    return () => el.removeEventListener('click', handler);
  }, [onPeek, citations]);

  return (
    <div ref={rootRef} style={{
      fontFamily: AS_FONT, fontSize, lineHeight: 1.62, color: '#1A1A1A',
      marginBottom: 14,
    }}>
      {paragraphs.map((para, i) => (
        <AttributedParagraph
          key={i}
          segments={para}
          hoveredId={hoveredId}
          onHover={setHoveredId}
          citations={citations}
          MODELS_BY_ID={MODELS_BY_ID}
          marginBottom={paraGap}
          hideEdge={hideEdges}
        />
      ))}
    </div>
  );
}

function AttributedParagraph({ segments, hoveredId, onHover, citations, MODELS_BY_ID, marginBottom = 10, hideEdge = false }) {
  MODELS_BY_ID = MODELS_BY_ID || window.MODELS_BY_ID || {};

  // lead is the mind with most chars in this paragraph
  const lead = React.useMemo(() => {
    const totals = {};
    segments.forEach(s => { totals[s.modelId] = (totals[s.modelId] || 0) + (s.text.length || 1); });
    return Object.entries(totals).sort((a,b) => b[1] - a[1])[0]?.[0];
  }, [segments]);

  const leadColor  = MODELS_BY_ID[lead]?.color || '#999';
  const edgeColor  = hoveredId ? (MODELS_BY_ID[hoveredId]?.color || '#999') : leadColor;

  return (
    <p style={{
      margin: `0 0 ${marginBottom}px`,
      padding: hideEdge ? '4px 0' : '4px 0 4px 14px',
      borderLeft: hideEdge ? 'none' : `2.5px solid ${edgeColor}`,
      transition: 'border-color 150ms',
      position: 'relative',
    }}>
      {segments.map((seg, i) => {
        const m = MODELS_BY_ID[seg.modelId] || { color: '#999' };
        const isHover = hoveredId === seg.modelId;
        const isDim   = hoveredId && !isHover;
        return (
          <span key={i}
            onMouseEnter={() => onHover(seg.modelId)}
            onMouseLeave={() => onHover(null)}
            style={{
              transition: 'color 150ms, background 150ms',
              color: isDim ? 'rgba(0,0,0,0.38)' : '#1A1A1A',
              background: isHover ? `${m.color}14` : 'transparent',
              borderRadius: 3,
              padding: isHover ? '1px 2px' : '1px 0',
              margin:  isHover ? '0 -2px' : '0',
              textDecoration: isHover ? `underline ${m.color}` : 'none',
              textUnderlineOffset: 3,
              cursor: 'default',
            }}
            dangerouslySetInnerHTML={{
              __html: richifyWithCitations(seg.text, seg.citations || [], citations),
            }}
          />
        );
      })}
    </p>
  );
}

// Exports
Object.assign(window, {
  AttributedSynthesis, AttributedParagraph,
  richifyWithCitations, renderCiteMarkup,
});
