// chat-elements.jsx — Inline UI components rendered inside AI briefings
//
// The chat is not a chat. It is an intelligence briefing surface with
// embedded UI: citation tables, axis cards, atom clusters, comparison
// charts, source-document previews. Built from atoms — every element
// traces back to a source via [n] citation refs.

// ────────────────────────────────────────────────────────────
// Inline axis card — shows score + progress + note for a specific axis
// ────────────────────────────────────────────────────────────
function InlineAxisCard({ axis, score, rag, note }) {
  const ragColor = { red: 'var(--red)', amber: 'var(--amber)', green: 'var(--green)' }[rag];
  return (
    <div style={{
      background: 'var(--elev-1)', padding: '16px 18px',
      display: 'grid', gridTemplateColumns: '1fr auto',
      gap: 16, alignItems: 'center', marginTop: 14,
    }}>
      <div style={{ minWidth: 0 }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
          <RagDot rag={rag} size={6} />
          <span style={{ fontFamily: 'var(--mono)', fontSize: 9,
            letterSpacing: '0.16em', textTransform: 'uppercase', color: ragColor }}>{rag}</span>
          <span style={{ fontFamily: 'var(--mono)', fontSize: 9,
            letterSpacing: '0.14em', color: 'var(--ink-3)' }}>· AXIS</span>
        </div>
        <div style={{ fontFamily: 'var(--serif)', fontSize: 22, lineHeight: 1.1,
          color: 'var(--ink)', marginTop: 6, letterSpacing: '-0.01em' }}>
          {axis}
        </div>
        {note && (
          <div style={{ fontSize: 12, color: 'var(--ink-2)', marginTop: 6, lineHeight: 1.45 }}>
            {note}
          </div>
        )}
        <div style={{ marginTop: 10 }}>
          <AxisBar score={score} rag={rag} h={3} bg="var(--elev-3)" />
        </div>
      </div>
      <div style={{ textAlign: 'right' }}>
        <div className="serif-num" style={{ fontSize: 44, lineHeight: 1, color: 'var(--ink)' }}>
          {score}
        </div>
        <div style={{ fontFamily: 'var(--mono)', fontSize: 9,
          letterSpacing: '0.16em', color: 'var(--ink-3)', textTransform: 'uppercase',
          marginTop: 4 }}>/ 100</div>
      </div>
    </div>
  );
}

// ────────────────────────────────────────────────────────────
// Inline source preview card — with excerpt + provenance
// ────────────────────────────────────────────────────────────
function InlineSourceCard({ sourceId, highlight }) {
  const s = SOURCE_BY_ID[sourceId];
  if (!s) return null;
  return (
    <div style={{
      background: 'var(--elev-1)', padding: '14px 16px', marginTop: 12,
      display: 'flex', flexDirection: 'column', gap: 10,
    }}>
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline' }}>
        <div style={{ display: 'flex', gap: 10, alignItems: 'baseline' }}>
          <span style={{ fontFamily: 'var(--mono)', fontSize: 9, letterSpacing: '0.16em',
            textTransform: 'uppercase', color: 'var(--gold)' }}>{KIND_LABEL[s.kind]}</span>
          <span style={{ fontFamily: 'var(--mono)', fontSize: 9, letterSpacing: '0.14em',
            color: 'var(--ink-3)' }}>· {s.origin}</span>
        </div>
        <span style={{ fontFamily: 'var(--mono)', fontSize: 9, color: 'var(--ink-3)' }}>
          {s.date}
        </span>
      </div>
      <div style={{ fontFamily: 'var(--serif)', fontSize: 17, lineHeight: 1.3,
        color: 'var(--ink)' }}>{s.title}</div>
      <div style={{ fontFamily: 'var(--serif)', fontSize: 14, lineHeight: 1.5,
        color: 'var(--ink-2)', fontStyle: 'italic' }}>
        {highlight ? (
          <span>"{s.excerpt.split(highlight).map((part, i, arr) => (
            <React.Fragment key={i}>
              {part}
              {i < arr.length - 1 && (
                <mark style={{ background: 'var(--amber-deep)', color: 'var(--amber)',
                  padding: '0 3px' }}>{highlight}</mark>
              )}
            </React.Fragment>
          ))}"</span>
        ) : (
          <span>"{s.excerpt}"</span>
        )}
      </div>
      <div style={{ display: 'flex', justifyContent: 'space-between',
        fontFamily: 'var(--mono)', fontSize: 9, letterSpacing: '0.14em',
        textTransform: 'uppercase', color: 'var(--ink-3)' }}>
        <span>{s.pages ? `${s.pages}pp · ` : ''}{s.atoms} atoms extracted</span>
        <span>Open document →</span>
      </div>
    </div>
  );
}

// ────────────────────────────────────────────────────────────
// Inline citation table — Kind / Title / Confidence / Provenance
// (The user's existing notebook prototype uses this exact column set)
// ────────────────────────────────────────────────────────────
function InlineCitationTable({ atoms, compact = false }) {
  if (!atoms || atoms.length === 0) return null;
  return (
    <div style={{ marginTop: 14, background: 'var(--surface)' }}>
      <div style={{ padding: '10px 16px', display: 'grid',
        gridTemplateColumns: compact ? '60px 1fr 50px' : '70px 1fr 70px 110px',
        gap: 14, borderBottom: '1px solid var(--elev-2)',
        fontFamily: 'var(--mono)', fontSize: 9, letterSpacing: '0.16em',
        textTransform: 'uppercase', color: 'var(--ink-3)' }}>
        <span>Kind</span>
        <span>Atom · Title</span>
        {!compact && <span>Conf</span>}
        <span style={{ textAlign: 'right' }}>Provenance</span>
      </div>
      {atoms.map((aid, i) => {
        const a = ATOM_BY_ID[aid];
        if (!a) return null;
        const s = SOURCE_BY_ID[a.src];
        return (
          <div key={aid + i} style={{
            padding: '12px 16px', display: 'grid',
            gridTemplateColumns: compact ? '60px 1fr 50px' : '70px 1fr 70px 110px',
            gap: 14, borderBottom: '1px solid var(--elev-1)', alignItems: 'center',
          }}>
            <span style={{ fontFamily: 'var(--mono)', fontSize: 9, letterSpacing: '0.14em',
              color: 'var(--gold)' }}>{KIND_LABEL[s?.kind] || 'ATOM'}</span>
            <span style={{ minWidth: 0 }}>
              <div style={{ fontSize: compact ? 12 : 13, color: 'var(--ink)',
                lineHeight: 1.35, overflow: 'hidden',
                textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
                {a.label || a.id}
              </div>
              {!compact && (
                <div style={{ fontFamily: 'var(--mono)', fontSize: 9, letterSpacing: '0.14em',
                  textTransform: 'uppercase', color: 'var(--ink-3)', marginTop: 2 }}>
                  {AXES.find(x => x.key === a.axis)?.label || a.axis}
                </div>
              )}
            </span>
            {!compact && (
              <span style={{ fontFamily: 'var(--mono)', fontSize: 11, color: 'var(--ink-2)' }}>
                {Math.round(a.conf * 100)}%
              </span>
            )}
            <span style={{ fontFamily: 'var(--mono)', fontSize: 10, color: 'var(--ink-3)',
              textAlign: 'right', overflow: 'hidden', textOverflow: 'ellipsis',
              whiteSpace: 'nowrap' }}>
              {(s?.title || '—').slice(0, compact ? 12 : 18)}
            </span>
          </div>
        );
      })}
    </div>
  );
}

// ────────────────────────────────────────────────────────────
// Inline atom cluster — mini graph showing the cited atoms
// ────────────────────────────────────────────────────────────
function InlineAtomCluster({ atoms, width = 280, height = 140 }) {
  if (!atoms || atoms.length === 0) return null;
  const nodes = atoms.map(aid => ATOM_BY_ID[aid]).filter(Boolean);

  // tighter normalized space for the cluster
  const minX = Math.min(...nodes.map(n => n.x));
  const maxX = Math.max(...nodes.map(n => n.x));
  const minY = Math.min(...nodes.map(n => n.y));
  const maxY = Math.max(...nodes.map(n => n.y));
  const rngX = Math.max(0.1, maxX - minX);
  const rngY = Math.max(0.1, maxY - minY);

  const mapX = (x) => 20 + ((x - minX) / rngX) * (width - 40);
  const mapY = (y) => 20 + ((y - minY) / rngY) * (height - 40);

  // edges between these nodes only
  const edges = [];
  nodes.forEach(a => (a.edges || []).forEach(e => {
    if (atoms.includes(e)) edges.push({ a, b: ATOM_BY_ID[e] });
  }));

  const ragColor = { red: 'var(--red)', amber: 'var(--amber)', green: 'var(--green)' };

  return (
    <div style={{ marginTop: 14, padding: '14px 0',
      background: 'var(--elev-1)', position: 'relative' }}>
      <div style={{ padding: '0 18px 8px' }}>
        <Kicker>Atom cluster · {nodes.length} nodes</Kicker>
      </div>
      <svg width="100%" viewBox={`0 0 ${width} ${height}`}
        preserveAspectRatio="xMidYMid meet" style={{ display: 'block' }}>
        {edges.map((e, i) => (
          <line key={i}
            x1={mapX(e.a.x)} y1={mapY(e.a.y)}
            x2={mapX(e.b.x)} y2={mapY(e.b.y)}
            stroke="var(--ink-3)" strokeWidth="0.7" opacity="0.6"/>
        ))}
        {nodes.map((a) => (
          <g key={a.id}>
            <circle cx={mapX(a.x)} cy={mapY(a.y)} r={5}
              fill={ragColor[a.rag]}/>
            <text x={mapX(a.x) + 10} y={mapY(a.y) + 3}
              fill="var(--ink-2)" fontFamily="var(--mono)" fontSize="9">
              {a.label || a.id}
            </text>
          </g>
        ))}
      </svg>
    </div>
  );
}

// ────────────────────────────────────────────────────────────
// Inline portfolio comparison — this co vs portfolio on this axis
// ────────────────────────────────────────────────────────────
function InlineComparison({ axisKey, focusCompanyId, label }) {
  const axisIdx = AXES.findIndex(a => a.key === axisKey);
  if (axisIdx < 0) return null;
  const rows = COMPANIES.map(c => ({
    id: c.id, name: c.name, score: c.axes[axisIdx],
    rag: ragOf(c.axes[axisIdx]),
    primary: c.id === focusCompanyId,
  })).sort((a, b) => b.score - a.score);
  const max = 100;
  return (
    <div style={{ marginTop: 14, padding: '14px 18px', background: 'var(--elev-1)' }}>
      <Kicker>Portfolio comparison · {label}</Kicker>
      <div style={{ marginTop: 12, display: 'flex', flexDirection: 'column', gap: 6 }}>
        {rows.map(r => {
          const ragColor = { red: 'var(--red)', amber: 'var(--amber)', green: 'var(--green)' }[r.rag];
          return (
            <div key={r.id} style={{ display: 'grid',
              gridTemplateColumns: '100px 1fr 40px', gap: 12, alignItems: 'center' }}>
              <span style={{ fontFamily: 'var(--mono)', fontSize: 11,
                color: r.primary ? 'var(--ink)' : 'var(--ink-3)',
                fontWeight: r.primary ? 600 : 400 }}>
                {r.name}
                {r.primary && <span style={{ marginLeft: 6, color: 'var(--gold)' }}>●</span>}
              </span>
              <div style={{ height: r.primary ? 12 : 6, background: 'var(--elev-3)',
                position: 'relative' }}>
                <div style={{ position: 'absolute', inset: 0, width: `${(r.score / max) * 100}%`,
                  background: ragColor, opacity: r.primary ? 1 : 0.55 }} />
              </div>
              <span style={{ fontFamily: 'var(--mono)', fontSize: 11, textAlign: 'right',
                color: r.primary ? 'var(--ink)' : 'var(--ink-2)' }}>{r.score}</span>
            </div>
          );
        })}
      </div>
    </div>
  );
}

// ────────────────────────────────────────────────────────────
// Pre-canned brief: rich version for AI Durability
// Used by both mobile + desktop chat.
// ────────────────────────────────────────────────────────────
const RICH_BRIEF_AI = {
  lead: 'AI durability is Smithfield\'s most exposed flank — 61 / 100 (Amber). The matching engine is well-engineered but data is not proprietary, so no flywheel compounds as Veritas and DataBridge enter the adjacent market. The owner of any defensibility play is unidentified while the CTO seat sits vacant.',
  axis: { name: 'AI Durability', score: 61, rag: 'amber',
    note: 'Score has held at 61 for three weeks. Competitor pressure is the catalyst for downside revision.' },
  citedAtoms: ['a-flywheel', 'a-veritas', 'a-databridge', 'a-cto', 'a-defensibility', 'a-not-ai'],
  cluster: ['a-flywheel', 'a-veritas', 'a-cto', 'a-defensibility', 'a-not-ai'],
  signals: [
    { t: 'Matching engine processes 2.3M txns/day · no proprietary dataset', src: 'Tech Audit Q1', ref: 1, atom: 'a-flywheel' },
    { t: 'CEO frames AI as "a feature, not the company"', src: 'CEO Interview', ref: 7, atom: 'a-defensibility' },
    { t: 'Veritas raised £14m Series B targeting adjacent workflow', src: 'Competitor Teardown', ref: 4, atom: 'a-veritas' },
    { t: 'CTO seat vacant since March — owner of defensibility play unidentified', src: 'Team Bios', ref: 5, atom: 'a-cto' },
  ],
  compareAxis: 'ai',
  verdict: 'Raise at the Series B board: commit to a data-partnership thesis or proprietary corpus before next round. Recommend conditioning the next cheque on a CTO hire and a written defensibility plan within 60 days.',
  confidence: 'HIGH',
  atoms: 24,
  sources: 6,
};

Object.assign(window, {
  InlineAxisCard, InlineSourceCard, InlineCitationTable, InlineAtomCluster, InlineComparison,
  RICH_BRIEF_AI,
});
