// gen-ui-artifact.jsx — §04d Generative UI + Workspace Artifact
//
// Real surfaces: src/renderer/windows/main/components/{chart, generative-ui,
// media-preview/WidgetRenderer, workspace-artifact}, plus MermaidRenderer in
// src/renderer/viewers/mermaid and KaTeX styles in src/renderer/styles.
//
// Charts/figures are mocked with pure SVG — we don't import recharts here,
// just need the visual silhouette so design audits make sense.

// -- Pie chart (Ghast chart/PieChart.tsx silhouette) --
function GenPieChart({ dark }) {
  const t = dark ? G.d : G.l;
  // Slices: arc paths sized to %.
  const slices = [
    { pct: 0.42, color: t.fg, label: 'Anthropic' },
    { pct: 0.27, color: t.fg2, label: 'OpenAI' },
    { pct: 0.18, color: t.fg3, label: 'Local' },
    { pct: 0.13, color: t.fg4, label: 'Other' },
  ];
  // Build SVG arcs.
  let acc = 0;
  const cx = 70, cy = 70, r = 60;
  const arcs = slices.map((s) => {
    const a0 = acc * 2 * Math.PI - Math.PI / 2;
    acc += s.pct;
    const a1 = acc * 2 * Math.PI - Math.PI / 2;
    const x0 = cx + r * Math.cos(a0), y0 = cy + r * Math.sin(a0);
    const x1 = cx + r * Math.cos(a1), y1 = cy + r * Math.sin(a1);
    const large = s.pct > 0.5 ? 1 : 0;
    return { d: `M${cx},${cy} L${x0},${y0} A${r},${r} 0 ${large} 1 ${x1},${y1} Z`, color: s.color };
  });
  return (
    <ChatLayout dark={dark} title="Provider usage">
      <UserMsg dark={dark}>Show me last month's usage by provider as a pie chart.</UserMsg>
      <div style={{
        maxWidth: 560, padding: 18,
        background: t.surface, border: `1px solid ${t.border}`, borderRadius: 14,
        display: 'flex', alignItems: 'center', gap: 24,
      }}>
        <svg width={140} height={140} viewBox="0 0 140 140">
          {arcs.map((a, i) => <path key={i} d={a.d} fill={a.color} />)}
          <circle cx={cx} cy={cy} r={26} fill={t.surface} />
        </svg>
        <div style={{ flex: 1 }}>
          {slices.map((s, i) => (
            <div key={i} style={{ display: 'flex', alignItems: 'center', gap: 8, padding: '4px 0', fontSize: 12 }}>
              <span style={{ width: 10, height: 10, borderRadius: 2, background: s.color, flexShrink: 0 }} />
              <span style={{ flex: 1, color: t.fg2 }}>{s.label}</span>
              <span style={{ fontFamily: G.mono, color: t.fg3 }}>{Math.round(s.pct * 100)}%</span>
            </div>
          ))}
        </div>
      </div>
    </ChatLayout>
  );
}


// ── Bar chart (vendor-icons/BarChart.tsx) ──
function GenBarChart({ dark }) {
  const t = dark ? G.d : G.l;
  const data = [
    { d: 'Mon', v: 0.62 }, { d: 'Tue', v: 0.78 }, { d: 'Wed', v: 0.45 },
    { d: 'Thu', v: 0.91 }, { d: 'Fri', v: 0.73 }, { d: 'Sat', v: 0.34 },
    { d: 'Sun', v: 0.51 },
  ];
  const W = 480, H = 180, pad = 22;
  const bw = (W - pad * 2) / data.length - 6;
  return (
    <ChatLayout dark={dark} title="Daily token usage">
      <UserMsg dark={dark}>Plot tokens spent per day this week as bars.</UserMsg>
      <div style={{
        maxWidth: 560, padding: 18,
        background: t.surface, border: `1px solid ${t.border}`, borderRadius: 14,
      }}>
        <svg width={W} height={H + 30} style={{ display: 'block' }}>
          {/* axis */}
          <line x1={pad} y1={H - pad} x2={W - pad} y2={H - pad} stroke={t.border} strokeWidth="1" />
          {data.map((d, i) => {
            const h = (H - pad * 2) * d.v;
            const x = pad + i * ((W - pad * 2) / data.length) + 3;
            return (
              <g key={i}>
                <rect x={x} y={H - pad - h} width={bw} height={h} fill={t.fg} rx={2} />
                <text x={x + bw / 2} y={H - pad + 14} fontFamily={G.mono} fontSize="10" fill={t.fg3} textAnchor="middle">{d.d}</text>
                <text x={x + bw / 2} y={H - pad - h - 4} fontFamily={G.mono} fontSize="9" fill={t.fg2} textAnchor="middle">{Math.round(d.v * 200)}k</text>
              </g>
            );
          })}
        </svg>
      </div>
    </ChatLayout>
  );
}


// ── Combined chart (bar + line overlay) ──
function GenCombinedChart({ dark }) {
  const t = dark ? G.d : G.l;
  const data = [62, 78, 45, 91, 73, 34, 51];
  const W = 480, H = 180, pad = 22;
  const bw = (W - pad * 2) / data.length - 6;
  // Trend line points
  const pts = data.map((v, i) => {
    const x = pad + i * ((W - pad * 2) / data.length) + bw / 2 + 3;
    const y = H - pad - (H - pad * 2) * (v / 100) * 0.8 - 8;
    return [x, y];
  });
  const linePath = pts.map(([x, y], i) => (i === 0 ? `M${x},${y}` : `L${x},${y}`)).join(' ');
  return (
    <ChatLayout dark={dark} title="Cost vs latency">
      <UserMsg dark={dark}>Show me cost (bars) and median latency (line) by day.</UserMsg>
      <div style={{
        maxWidth: 560, padding: 18,
        background: t.surface, border: `1px solid ${t.border}`, borderRadius: 14,
      }}>
        <svg width={W} height={H + 30} style={{ display: 'block' }}>
          <line x1={pad} y1={H - pad} x2={W - pad} y2={H - pad} stroke={t.border} strokeWidth="1" />
          {data.map((v, i) => {
            const h = (H - pad * 2) * (v / 100) * 0.7;
            const x = pad + i * ((W - pad * 2) / data.length) + 3;
            return <rect key={i} x={x} y={H - pad - h} width={bw} height={h} fill={t.fg2} rx={2} />;
          })}
          <path d={linePath} fill="none" stroke={t.fg} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
          {pts.map(([x, y], i) => (
            <circle key={i} cx={x} cy={y} r={3} fill={t.surface} stroke={t.fg} strokeWidth="2" />
          ))}
        </svg>
        <div style={{ display: 'flex', gap: 16, justifyContent: 'center', marginTop: 4, fontSize: 11, color: t.fg3 }}>
          <span><span style={{ display: 'inline-block', width: 10, height: 8, background: t.fg2, marginRight: 4, borderRadius: 1 }} />Cost (USD)</span>
          <span><span style={{ display: 'inline-block', width: 14, height: 2, background: t.fg, marginRight: 4, verticalAlign: 'middle' }} />Latency (ms)</span>
        </div>
      </div>
    </ChatLayout>
  );
}


// ── Scatter plot ──
function GenScatterChart({ dark }) {
  const t = dark ? G.d : G.l;
  const dots = [];
  // Deterministic pseudo-random distribution.
  for (let i = 0; i < 60; i++) {
    const x = (Math.sin(i * 12.9898) * 43758.5453 + 1) / 2;
    const y = (Math.cos(i * 4.1414) * 13758.5453 + 1) / 2;
    dots.push({
      x: 30 + (x % 1) * 420,
      y: 20 + (y % 1) * 130,
      r: 2 + ((x * 7) % 1) * 4,
      tone: i % 3 === 0 ? t.fg : (i % 3 === 1 ? t.fg2 : t.fg3),
    });
  }
  return (
    <ChatLayout dark={dark} title="Latency distribution">
      <UserMsg dark={dark}>Plot all 60 latency samples as a scatter.</UserMsg>
      <div style={{
        maxWidth: 560, padding: 18,
        background: t.surface, border: `1px solid ${t.border}`, borderRadius: 14,
      }}>
        <svg width={480} height={180}>
          <line x1={20} y1={170} x2={460} y2={170} stroke={t.border} strokeWidth="1" />
          <line x1={20} y1={10} x2={20} y2={170} stroke={t.border} strokeWidth="1" />
          {dots.map((d, i) => <circle key={i} cx={d.x} cy={d.y} r={d.r} fill={d.tone} fillOpacity="0.7" />)}
        </svg>
      </div>
    </ChatLayout>
  );
}


// ── Widget renderer (sandboxed iframe HTML/SVG visualization) ──
function GenWidgetRenderer({ dark, variant = 'algorithm' }) {
  const t = dark ? G.d : G.l;
  return (
    <ChatLayout dark={dark} title="Visualize binary search">
      <UserMsg dark={dark}>{variant === 'algorithm' ? 'Visualize binary search on this sorted array.' : 'Build me a particle simulation with damping.'}</UserMsg>
      <div style={{
        maxWidth: 720, padding: 0,
        background: t.surface, border: `1px solid ${t.border}`, borderRadius: 14, overflow: 'hidden',
      }}>
        <div style={{
          padding: '8px 14px', background: t.surface2,
          borderBottom: `0.5px solid ${t.border2}`,
          display: 'flex', alignItems: 'center', gap: 8,
          fontSize: 11, fontFamily: G.mono, color: t.fg2,
        }}>
          <Icon name="cube" size={11} color={t.fg2} />
          <span style={{ color: t.fg }}>widget</span>
          <span>· sandboxed iframe</span>
          <span style={{ flex: 1 }} />
          <Tag style={{ height: 18, fontSize: 9 }}>html · 4 KB</Tag>
        </div>
        {/* Mock widget body */}
        <div style={{
          padding: 24, height: 220, position: 'relative',
          background: dark ? '#101010' : '#fafafa',
          backgroundImage: `linear-gradient(${t.border} 1px, transparent 1px), linear-gradient(90deg, ${t.border} 1px, transparent 1px)`,
          backgroundSize: '24px 24px',
        }}>
          {variant === 'algorithm' ? (
            <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', height: '100%', gap: 6 }}>
              {[2, 5, 8, 12, 16, 23, 27, 34, 42, 56, 71].map((n, i) => {
                const isLow = i === 0, isHigh = i === 10, isMid = i === 5, isFound = i === 5;
                return (
                  <div key={i} style={{
                    width: 36, height: 36, borderRadius: 8,
                    background: isFound ? t.fg : (isMid ? t.fg2 : t.surface),
                    color: isFound || isMid ? t.bg : t.fg2,
                    border: `1.5px solid ${isLow || isHigh ? '#5865F2' : t.border}`,
                    display: 'flex', alignItems: 'center', justifyContent: 'center',
                    fontFamily: G.mono, fontSize: 12, fontWeight: 600, position: 'relative',
                  }}>
                    {n}
                    {isLow && <span style={{ position: 'absolute', bottom: -16, fontSize: 9, color: '#5865F2' }}>lo</span>}
                    {isHigh && <span style={{ position: 'absolute', bottom: -16, fontSize: 9, color: '#5865F2' }}>hi</span>}
                    {isMid && <span style={{ position: 'absolute', top: -16, fontSize: 9, color: t.fg }}>mid · ✓</span>}
                  </div>
                );
              })}
            </div>
          ) : (
            <div style={{ height: '100%', display: 'flex', alignItems: 'center', justifyContent: 'center', position: 'relative' }}>
              {/* Particle dots */}
              {Array.from({ length: 18 }).map((_, i) => {
                const a = (i / 18) * Math.PI * 2;
                return <div key={i} style={{
                  position: 'absolute',
                  width: 6, height: 6, borderRadius: 3, background: t.fg,
                  left: `calc(50% + ${Math.cos(a) * (40 + i * 2)}px)`,
                  top: `calc(50% + ${Math.sin(a) * (40 + i * 2)}px)`,
                  opacity: 0.6,
                }} />;
              })}
              <div style={{ width: 12, height: 12, borderRadius: 6, background: t.fg }} />
            </div>
          )}
        </div>
        <div style={{ padding: '8px 14px', borderTop: `0.5px solid ${t.border2}`, display: 'flex', alignItems: 'center', gap: 6 }}>
          <button style={{ width: 26, height: 26, borderRadius: 6, background: 'transparent', border: 'none', color: t.fg2, cursor: 'pointer' }}><Icon name="play" size={11} /></button>
          <button style={{ width: 26, height: 26, borderRadius: 6, background: 'transparent', border: 'none', color: t.fg2, cursor: 'pointer' }}><Icon name="refresh" size={11} /></button>
          <button style={{ width: 26, height: 26, borderRadius: 6, background: 'transparent', border: 'none', color: t.fg2, cursor: 'pointer' }}><Icon name="code" size={11} /></button>
          <span style={{ flex: 1 }} />
          <span style={{ fontSize: 11, fontFamily: G.mono, color: t.fg3 }}>iframe sandbox · no network</span>
        </div>
      </div>
    </ChatLayout>
  );
}


// ── Mermaid diagram (flowchart / sequence) ──
function GenMermaid({ dark, variant = 'flowchart' }) {
  const t = dark ? G.d : G.l;
  return (
    <ChatLayout dark={dark} title="Auth pipeline diagram">
      <UserMsg dark={dark}>{variant === 'flowchart' ? 'Diagram the auth flow.' : 'Sequence diagram of a JWT refresh.'}</UserMsg>
      <div style={{
        maxWidth: 720, padding: 0,
        background: t.surface, border: `1px solid ${t.border}`, borderRadius: 14, overflow: 'hidden',
      }}>
        <div style={{
          padding: '8px 14px', background: t.surface2,
          borderBottom: `0.5px solid ${t.border2}`,
          display: 'flex', alignItems: 'center', gap: 8,
          fontSize: 11, fontFamily: G.mono, color: t.fg2,
        }}>
          <Icon name="workflow" size={11} color={t.fg2} />
          <span style={{ color: t.fg }}>mermaid</span>
          <span>· {variant}</span>
          <span style={{ flex: 1 }} />
          <button style={{ background: 'transparent', border: 'none', color: t.fg3, fontSize: 11, fontFamily: G.mono, cursor: 'pointer' }}>view source</button>
        </div>
        <div style={{ padding: 28, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
          {variant === 'flowchart' ? (
            <svg width={520} height={180}>
              {/* Nodes */}
              {[
                { x: 40, y: 70, w: 90, h: 40, label: 'Request', round: 20 },
                { x: 180, y: 30, w: 110, h: 40, label: 'Has cookie?', diamond: true },
                { x: 340, y: 30, w: 90, h: 40, label: '401', round: 6 },
                { x: 180, y: 110, w: 110, h: 40, label: 'verifyJwt', round: 6 },
                { x: 340, y: 110, w: 90, h: 40, label: 'next()', round: 20 },
              ].map((n, i) => (
                <g key={i}>
                  <rect x={n.x} y={n.y} width={n.w} height={n.h} rx={n.round} fill={t.surface2} stroke={t.fg} strokeWidth="1.5" />
                  <text x={n.x + n.w / 2} y={n.y + n.h / 2 + 4} textAnchor="middle" fontFamily={G.mono} fontSize="11" fill={t.fg}>{n.label}</text>
                </g>
              ))}
              {/* Arrows */}
              {[
                { x1: 130, y1: 90, x2: 180, y2: 50 },
                { x1: 130, y1: 90, x2: 180, y2: 130 },
                { x1: 290, y1: 50, x2: 340, y2: 50 },
                { x1: 290, y1: 130, x2: 340, y2: 130 },
              ].map((a, i) => (
                <line key={i} x1={a.x1} y1={a.y1} x2={a.x2} y2={a.y2} stroke={t.fg2} strokeWidth="1.5" markerEnd="url(#arr)" />
              ))}
              <defs>
                <marker id="arr" markerWidth="10" markerHeight="10" refX="8" refY="3" orient="auto">
                  <path d="M0,0 L0,6 L8,3 z" fill={t.fg2} />
                </marker>
              </defs>
            </svg>
          ) : (
            <svg width={520} height={200}>
              {/* Lifelines */}
              {[
                { x: 80, label: 'Client' },
                { x: 240, label: 'Auth' },
                { x: 400, label: 'JWKS' },
              ].map((l, i) => (
                <g key={i}>
                  <rect x={l.x - 40} y={10} width={80} height={26} rx={4} fill={t.surface2} stroke={t.fg} strokeWidth="1.2" />
                  <text x={l.x} y={28} textAnchor="middle" fontFamily={G.mono} fontSize="11" fill={t.fg}>{l.label}</text>
                  <line x1={l.x} y1={36} x2={l.x} y2={190} stroke={t.border} strokeDasharray="3 3" />
                </g>
              ))}
              {/* Messages */}
              {[
                { y: 60, x1: 80, x2: 240, label: 'POST /refresh' },
                { y: 95, x1: 240, x2: 400, label: 'GET /.well-known/jwks' },
                { y: 130, x1: 400, x2: 240, label: 'keys[]', dashed: true },
                { y: 165, x1: 240, x2: 80, label: '200 + new JWT' },
              ].map((m, i) => (
                <g key={i}>
                  <line x1={m.x1} y1={m.y} x2={m.x2} y2={m.y} stroke={t.fg2} strokeWidth="1.5" strokeDasharray={m.dashed ? '4 3' : '0'} markerEnd="url(#arr2)" />
                  <text x={(m.x1 + m.x2) / 2} y={m.y - 4} textAnchor="middle" fontFamily={G.mono} fontSize="10" fill={t.fg2}>{m.label}</text>
                </g>
              ))}
              <defs>
                <marker id="arr2" markerWidth="10" markerHeight="10" refX="8" refY="3" orient="auto">
                  <path d="M0,0 L0,6 L8,3 z" fill={t.fg2} />
                </marker>
              </defs>
            </svg>
          )}
        </div>
      </div>
    </ChatLayout>
  );
}


// ── KaTeX math (inline + block) ──
function GenKaTeX({ dark, variant = 'inline' }) {
  const t = dark ? G.d : G.l;
  // We can't load actual KaTeX in inline babel, so we use unicode + serif italic
  // to give a visual approximation that's good enough for design audits.
  const mathStyle = { fontFamily: 'KaTeX_Main, "Latin Modern Math", "Times New Roman", serif', fontStyle: 'italic', fontSize: 16, color: t.fg };
  return (
    <ChatLayout dark={dark} title="Quick math">
      <UserMsg dark={dark}>{variant === 'inline' ? 'What\'s the time complexity of binary search?' : 'Show me the loss function for cross-entropy.'}</UserMsg>
      {variant === 'inline' ? (
        <AssistantMsg dark={dark}>
          Binary search runs in <span style={{ ...mathStyle, padding: '0 4px' }}>O(log n)</span> time and{' '}
          <span style={{ ...mathStyle, padding: '0 4px' }}>O(1)</span> space, since each step halves the range{' '}
          <span style={{ ...mathStyle, padding: '0 4px' }}>[lo, hi]</span> until <span style={{ ...mathStyle, padding: '0 4px' }}>lo {'>'} hi</span>.
        </AssistantMsg>
      ) : (
        <>
          <AssistantMsg dark={dark}>Cross-entropy loss for a single sample with one-hot label:</AssistantMsg>
          <div style={{
            maxWidth: 720, padding: '20px 24px', textAlign: 'center',
            background: t.surface, border: `1px solid ${t.border}`, borderRadius: 14,
          }}>
            <div style={{ ...mathStyle, fontSize: 22, lineHeight: 1.6 }}>
              ℒ = − ∑<sub style={{ fontSize: 12 }}>i=1</sub><sup style={{ fontSize: 12 }}>C</sup> y<sub style={{ fontSize: 12 }}>i</sub> log(ŷ<sub style={{ fontSize: 12 }}>i</sub>)
            </div>
            <div style={{ marginTop: 12, fontSize: 11, color: t.fg3, fontFamily: G.mono }}>
              where C = number of classes, y = true label, ŷ = predicted distribution
            </div>
          </div>
        </>
      )}
    </ChatLayout>
  );
}


// ── Workspace Artifact panel (file tree + preview + actions) ──
function ArtifactPanel({ dark, variant = 'file' }) {
  const t = dark ? G.d : G.l;
  const isImage = variant === 'image';
  const isDiff = variant === 'diff';
  const tree = [
    { name: 'docs/', kind: 'dir', open: true },
    { name: '  audit-2026-05.md', kind: 'md', active: !isImage && !isDiff },
    { name: '  diagrams/', kind: 'dir', open: true },
    { name: '    auth-flow.svg', kind: 'svg', active: isImage },
    { name: 'src/', kind: 'dir', open: true },
    { name: '  middleware/', kind: 'dir', open: true },
    { name: '    auth.ts', kind: 'ts', active: isDiff, modified: true },
  ];

  return (
    <ChatLayout dark={dark} title="Auth audit artifact" rightPanel={
      <div style={{ height: '100%', display: 'flex', flexDirection: 'column' }}>
        <div style={{ padding: '10px 14px', borderBottom: `0.5px solid ${t.border}`, display: 'flex', alignItems: 'center', gap: 8 }}>
          <Icon name="folder" size={13} color={t.fg2} />
          <span style={{ fontSize: 12, fontWeight: 500 }}>auth-audit</span>
          <span style={{ flex: 1 }} />
          <button style={{ background: 'transparent', border: 'none', color: t.fg3, cursor: 'pointer' }}><Icon name="ext" size={12} /></button>
          <button style={{ background: 'transparent', border: 'none', color: t.fg3, cursor: 'pointer' }}><Icon name="download" size={12} /></button>
        </div>
        {/* File tree */}
        <div style={{ width: 200, borderRight: `0.5px solid ${t.border2}`, overflow: 'auto', padding: '8px 0', flexShrink: 0, fontFamily: G.mono, fontSize: 11, position: 'absolute', top: 38, bottom: 0, left: 0 }}>
          {tree.map((n, i) => (
            <div key={i} style={{
              padding: '4px 12px', display: 'flex', alignItems: 'center', gap: 6,
              background: n.active ? t.surface2 : 'transparent',
              color: n.active ? t.fg : t.fg2,
              cursor: 'pointer',
            }}>
              <Icon name={n.kind === 'dir' ? (n.open ? 'chevronDown' : 'chevronRight') : 'file'} size={9} color={t.fg3} />
              <span>{n.name}</span>
              {n.modified && <span style={{ marginLeft: 'auto', color: '#febc2e' }}>M</span>}
            </div>
          ))}
        </div>
        {/* Preview */}
        <div className="gh-scroll" style={{ flex: 1, overflow: 'auto', marginLeft: 200 }}>
          {variant === 'file' && (
            <div style={{ padding: '24px 28px', maxWidth: 600 }}>
              <div style={{ fontSize: 11, color: t.fg3, fontFamily: G.mono, marginBottom: 6 }}>docs/audit-2026-05.md</div>
              <h1 style={{ fontSize: 20, fontWeight: 600, margin: '0 0 10px' }}>Auth Middleware Audit</h1>
              <p style={{ fontSize: 12, color: t.fg2, lineHeight: 1.6 }}>
                Audit of <code style={{ fontFamily: G.mono, fontSize: 11 }}>src/middleware/auth.ts</code> performed 2026-05-04.
                Two HIGH-severity findings, three MEDIUM. Bypass on lines 5–7 has been removed in PR #4112.
              </p>
              <h2 style={{ fontSize: 14, fontWeight: 600, marginTop: 16 }}>Findings</h2>
              <ul style={{ fontSize: 12, color: t.fg2, lineHeight: 1.7, paddingLeft: 18 }}>
                <li>HIGH · X-Internal-Trust header bypass (auth.ts:5)</li>
                <li>HIGH · No rate limit on /verify (auth.ts:14)</li>
                <li>MEDIUM · Cookie not flagged HttpOnly</li>
              </ul>
            </div>
          )}
          {variant === 'image' && (
            <div style={{ padding: 28, display: 'flex', alignItems: 'center', justifyContent: 'center', height: '100%' }}>
              <ImgPlaceholder label="auth-flow.svg · 1200 × 800" height={300} style={{ width: 480 }} />
            </div>
          )}
          {variant === 'diff' && (
            <div style={{ padding: '8px 0', fontFamily: G.mono, fontSize: 11, lineHeight: 1.6 }}>
              <div style={{ padding: '6px 14px', fontSize: 11, color: t.fg3 }}>src/middleware/auth.ts · −4 / +1</div>
              {[
                { tone: t.fg3, text: '  4: const token = req.cookies.session;' },
                { tone: '#d44', bg: 'rgba(255,95,87,0.06)', text: '  5: if (req.headers[\'x-internal-trust\'] === \'true\') {' },
                { tone: '#d44', bg: 'rgba(255,95,87,0.06)', text: '  6:   return next();' },
                { tone: '#d44', bg: 'rgba(255,95,87,0.06)', text: '  7: }' },
                { tone: '#3a8', bg: 'rgba(40,200,64,0.06)', text: '  5: // removed unsafe bypass — see ADR-002' },
                { tone: t.fg3, text: '  6: try {' },
              ].map((l, i) => (
                <div key={i} style={{ padding: '0 14px', background: l.bg || 'transparent', color: l.tone, whiteSpace: 'pre' }}>{l.text}</div>
              ))}
            </div>
          )}
        </div>
      </div>
    }>
      <UserMsg dark={dark}>Open the audit artifact</UserMsg>
      <AssistantMsg dark={dark}>Opened in the side panel — file tree on the left, preview on the right.</AssistantMsg>
    </ChatLayout>
  );
}


// ── WorkspaceFilesPicker (@-mention to attach a file as context) ──
function ArtifactFilesPicker({ dark }) {
  const t = dark ? G.d : G.l;
  const items = [
    { name: 'src/middleware/auth.ts', kind: 'ts', match: 'auth' },
    { name: 'src/middleware/session.ts', kind: 'ts', match: 'auth' },
    { name: 'src/test/auth.test.ts', kind: 'ts', match: 'auth' },
    { name: 'docs/auth-flow.md', kind: 'md', match: 'auth' },
    { name: 'docs/auth-audit.md', kind: 'md', match: 'auth' },
  ];
  return (
    <ChatLayout dark={dark} title="Refactor auth middleware">
      <UserMsg dark={dark}>Compare @</UserMsg>
      {/* Picker popover */}
      <div style={{
        maxWidth: 480, padding: 0, marginTop: -8,
        background: t.surface, border: `1px solid ${t.border}`, borderRadius: 12,
        boxShadow: t.shadow,
      }}>
        <div style={{ padding: '8px 12px', borderBottom: `0.5px solid ${t.border2}`, display: 'flex', alignItems: 'center', gap: 8, fontSize: 11, color: t.fg3, fontFamily: G.mono }}>
          <Icon name="search" size={11} />
          <span>auth</span>
          <span style={{ flex: 1 }} />
          <Kbd>↑↓</Kbd> <Kbd>↵</Kbd> <Kbd>esc</Kbd>
        </div>
        {items.map((it, i) => (
          <div key={i} style={{
            padding: '7px 12px', display: 'flex', alignItems: 'center', gap: 8,
            fontSize: 12, fontFamily: G.mono, color: t.fg2,
            background: i === 0 ? t.surface2 : 'transparent',
            borderBottom: i === items.length - 1 ? 'none' : `0.5px solid ${t.border2}`,
          }}>
            <Icon name="file" size={11} color={t.fg3} />
            <span>{it.name.replace(/(auth)/g, x => x)}</span>
            <span style={{ flex: 1 }} />
            <Tag style={{ height: 16, fontSize: 9 }}>.{it.kind}</Tag>
          </div>
        ))}
      </div>
    </ChatLayout>
  );
}


Object.assign(window, {
  GenPieChart, GenBarChart, GenCombinedChart, GenScatterChart,
  GenWidgetRenderer, GenMermaid, GenKaTeX,
  ArtifactPanel, ArtifactFilesPicker,
});
