/* Report card — editorial layout with rich viz.
   Layout variants: editorial (default), dashboard, briefing. */

// ── Report footer (brand + copyright) ───────────────────────────────────────
function ReportFooter() {
  return (
    <div className="report-footer" style={{
      marginTop: 40, paddingTop: 16, borderTop: '1px solid var(--rule)',
      display: 'flex', alignItems: 'center', gap: 12,
      fontSize: 10, color: 'var(--ink-4)',
    }}>
      {window.CHISEL_LOGO_SRC && (
        <img src={window.CHISEL_LOGO_SRC} alt="Chisel"
          style={{ width: 30, height: 'auto', objectFit: 'contain', opacity: 0.75 }} />
      )}
      <div style={{ flex: 1 }}>
        <span style={{ fontWeight: 700, color: 'var(--ink-3)' }}>Learning Solutions @Chisel</span>
        {' · '}
        <strong>ChiselAssess</strong>
        {' — Tool by Technical Team'}
      </div>
      <div style={{ textAlign: 'right', lineHeight: 1.5 }}>
        <a href="https://www.ls-chisel.com" target="_blank" rel="noopener noreferrer"
          style={{ color: 'var(--accent)', textDecoration: 'none', fontWeight: 500 }}>
          www.ls-chisel.com
        </a>
        <br/>
        {'© ' + new Date().getFullYear() + ' All rights reserved'}
      </div>
    </div>
  );
}

function ReportView({ report, layout = 'editorial', cohortAvg, onBack }) {
  const r = report;
  const cohort = cohortAvg || CRITERIA.map(() => 68 + Math.random() * 10);
  const critValues = CRITERIA.map((c) => r.scores[c.key]);
  const axes = CRITERIA.map((c) => c.label.split(' ')[0]);

  // ── Brand bar ─────────────────────────────────────────────────────────────
  const brandBar = (
    <div style={{
      display: 'flex', alignItems: 'center', gap: 16,
      marginBottom: 22, paddingBottom: 16, borderBottom: '2px solid var(--rule)',
      background: 'linear-gradient(135deg, var(--paper-2) 0%, var(--paper-3) 100%)',
      padding: '16px 20px', borderRadius: 'var(--radius-lg)',
      border: '1px solid var(--rule)',
    }}>
      {window.CHISEL_LOGO_SRC && (
        <img src={window.CHISEL_LOGO_SRC} alt="Chisel"
          style={{ width: 56, height: 'auto', objectFit: 'contain', borderRadius: 0 }} />
      )}
      <div style={{ flex: 1 }}>
        <div style={{ fontSize: 18, fontWeight: 700, color: 'var(--ink)', lineHeight: 1.2, letterSpacing: '-0.01em' }}>
          Learning Solutions @Chisel
        </div>
        <div style={{ fontSize: 12, color: 'var(--ink-4)', marginTop: 3 }}>
          <strong>ChiselAssess</strong> — Voice Assessment Platform
        </div>
      </div>
      <div style={{ fontSize: 9, color: 'var(--ink-5)', textAlign: 'right', lineHeight: 1.6 }}>
        <a href="https://www.ls-chisel.com" target="_blank" rel="noopener noreferrer"
          style={{ color: 'var(--ink-4)', textDecoration: 'none', fontWeight: 500 }}>
          www.ls-chisel.com
        </a>
        <br/>{'© ' + new Date().getFullYear() + ' Learning Solutions @Chisel'}
      </div>
    </div>
  );

  const head = (
    <div>
      {brandBar}
      <div style={{ display: 'flex', alignItems: 'flex-start', justifyContent: 'space-between', gap: 20, marginBottom: 20, flexWrap: 'wrap' }}>
      <div>
        <div className="eyebrow mb-2">Evaluation Report · {r.id.toUpperCase()}</div>
        <h1 className="serif" style={{ fontSize: 36, lineHeight: 1.05, letterSpacing: '-0.012em', marginBottom: 6 }}>
          {r.topic}
        </h1>
        <div style={{ display: 'flex', alignItems: 'center', gap: 10, color: 'var(--ink-3)', fontSize: 12.5 }}>
          <Avatar name={r.student.name} size={24} seed={r.student.avatarSeed} />
          <span style={{ fontWeight: 500, color: 'var(--ink-2)' }}>{r.student.name}</span>
          <span className="mono">{r.student.regNo}</span>
          <span>·</span>
          <span>{r.student.dept}</span>
          <span>·</span>
          <span>{fmtDate(r.date)}, {fmtTime(r.date)}</span>
        </div>
      </div>
      <div style={{ display: 'flex', gap: 8 }} className="print-hide">
        {onBack && <button className="btn btn-sm" onClick={onBack}><Icon name="arrowLeft" size={12}/> Back</button>}
        <button className="btn btn-sm btn-primary" onClick={() => {
          const el = document.getElementById('report-print-root');
          const name = (r.student?.name || 'Report').replace(/\s+/g, '_');
          if (window.downloadElementAsPDF && el) {
            window.downloadElementAsPDF(el, `ChiselAssess_${name}_Report`);
          } else if (window.downloadReportAsPDF) {
            window.downloadReportAsPDF(r);
          }
        }}>
          <Icon name="download" size={12}/> Download PDF
        </button>
        <button className="btn btn-sm btn-ghost"><Icon name="dots" size={14}/></button>
      </div>
    </div>
    </div>
  );

  if (layout === 'dashboard') return <ReportDashboard r={r} head={head} cohort={cohort} critValues={critValues} axes={axes} />;
  if (layout === 'briefing')  return <ReportBriefing  r={r} head={head} cohort={cohort} critValues={critValues} axes={axes} />;
  return <ReportEditorial r={r} head={head} cohort={cohort} critValues={critValues} axes={axes} />;
}

// ── Editorial layout (hero) ──────────────────────────────
const CRIT_COLOR = ['--crit-content','--crit-structure','--crit-delivery','--crit-voice','--crit-engagement','--crit-visual'];
const CRIT_WASH  = ['--crit-content-w','--crit-structure-w','--crit-delivery-w','--crit-voice-w','--crit-engagement-w','--crit-visual-w'];

function ReportEditorial({ r, head, cohort, critValues, axes }) {
  return (
    <div className="fade-up" id="report-print-root" style={{ position: 'relative' }}>
      {/* Watermark */}
      {window.CHISEL_WATERMARK_SRC && (
        <div className="report-watermark" aria-hidden="true" style={{
          position: 'absolute', top: '50%', left: '50%',
          transform: 'translate(-50%, -50%)',
          width: 220, height: 295, opacity: 0.045,
          backgroundImage: `url(${window.CHISEL_WATERMARK_SRC})`,
          backgroundSize: 'contain', backgroundRepeat: 'no-repeat', backgroundPosition: 'center',
          pointerEvents: 'none', zIndex: 0,
        }}/>
      )}
      {head}
      {/* Colorful score hero */}
      <div style={{
        display: 'grid', gridTemplateColumns: '1fr 1fr 1fr 1fr 1fr 1fr', gap: 0,
        border: '1px solid var(--rule)', borderRadius: 'var(--radius-lg)', overflow: 'hidden',
        marginBottom: 24,
      }}>
        {CRITERIA.map((c, i) => {
          const v = r.scores[c.key];
          return (
            <div key={c.key} className="fade-up" style={{
              animationDelay: `${0.05 + i * 0.04}s`,
              padding: '16px 14px', background: `var(${CRIT_WASH[i]})`,
              borderRight: i < 5 ? '1px solid var(--rule)' : 'none',
              position: 'relative', overflow: 'hidden',
            }}>
              <div className="eyebrow" style={{ color: `var(${CRIT_COLOR[i]})` }}>{c.label.split(' ')[0]}</div>
              <div className="serif tnum" style={{ fontSize: 36, lineHeight: 1, marginTop: 4, color: `var(${CRIT_COLOR[i]})` }}>{v}</div>
              <div style={{ height: 3, background: 'rgba(0,0,0,0.08)', marginTop: 8, borderRadius: 2, overflow: 'hidden' }}>
                <div style={{ height: '100%', width: `${v}%`, background: `var(${CRIT_COLOR[i]})`, transition: 'width 1.2s cubic-bezier(.3,.7,.3,1)' }}/>
              </div>
            </div>
          );
        })}
      </div>
      <div style={{
        display: 'grid',
        gridTemplateColumns: '1.2fr 0.8fr',
        gap: 28,
        borderTop: '1px solid var(--rule)', paddingTop: 24,
      }}>
        <div>
          <div className="eyebrow mb-3">The Verdict</div>
          <div className="serif" style={{ fontSize: 22, lineHeight: 1.4, color: 'var(--ink-2)', marginBottom: 24, fontStyle: 'italic' }}>
            “{r.verdict}”
          </div>

          <div className="eyebrow mb-3">Performance by criterion</div>
          <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 14 }}>
            {CRITERIA.map((c, i) => {
              const v = r.scores[c.key];
              const g = gradeOf(v);
              return (
                <div key={c.key} className="fade-up" style={{ animationDelay: `${0.1 + i * 0.05}s`, padding: '14px 0', borderTop: i < 2 ? 'none' : '1px solid var(--rule)' }}>
                  <div style={{ display: 'flex', alignItems: 'baseline', justifyContent: 'space-between', marginBottom: 6 }}>
                    <div style={{ fontSize: 13, fontWeight: 500, display: 'flex', alignItems: 'center', gap: 8 }}>
                      <span style={{ width: 6, height: 6, borderRadius: '50%', background: `var(${CRIT_COLOR[i]})` }}/>
                      {c.label}
                    </div>
                    <div style={{ display: 'flex', alignItems: 'baseline', gap: 6 }}>
                      <span className="serif tnum" style={{ fontSize: 22, color: `var(${CRIT_COLOR[i]})` }}>{v}</span>
                      <span className="mono" style={{ fontSize: 10, color: `var(--${g.tone})` }}>{g.g}</span>
                    </div>
                  </div>
                  <div style={{ height: 4, background: `var(${CRIT_WASH[i]})`, borderRadius: 2, overflow: 'hidden', position: 'relative' }}>
                    <div style={{ position: 'absolute', inset: 0, width: `${v}%`, background: `var(${CRIT_COLOR[i]})`, transition: 'width 1s cubic-bezier(.3,.7,.3,1)' }} />
                  </div>
                  <div style={{ fontSize: 11, color: 'var(--ink-4)', marginTop: 6, fontStyle: 'italic', lineHeight: 1.5 }}>{c.desc}</div>
                </div>
              );
            })}
          </div>

          <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 14, marginTop: 28 }}>
            <div style={{ background: 'var(--ok-wash)', borderRadius: 'var(--radius-lg)', padding: '16px 18px', borderLeft: '3px solid var(--ok)' }}>
              <div className="eyebrow mb-2" style={{ color: 'var(--ok)' }}>✓ Strengths</div>
              {r.strengths.map((s, i) => (
                <div key={i} style={{ fontSize: 12.5, lineHeight: 1.6, color: 'var(--ink-2)', paddingLeft: 14, position: 'relative', marginBottom: 6 }}>
                  <span style={{ position: 'absolute', left: 0, color: 'var(--ok)', fontWeight: 600 }}>+</span>{s}
                </div>
              ))}
            </div>
            <div style={{ background: 'var(--warn-wash)', borderRadius: 'var(--radius-lg)', padding: '16px 18px', borderLeft: '3px solid var(--warn)' }}>
              <div className="eyebrow mb-2" style={{ color: 'var(--warn)' }}>△ To improve</div>
              {r.weaknesses.map((s, i) => (
                <div key={i} style={{ fontSize: 12.5, lineHeight: 1.6, color: 'var(--ink-2)', paddingLeft: 14, position: 'relative', marginBottom: 6 }}>
                  <span style={{ position: 'absolute', left: 0, color: 'var(--warn)', fontWeight: 600 }}>→</span>{s}
                </div>
              ))}
            </div>
          </div>
        </div>

        <div>
          {/* AI score ring */}
          <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', padding: '8px 0 14px', borderBottom: '1px solid var(--rule)', marginBottom: 14 }}>
            <ScoreRing value={r.scores.overall} max={10} label="of 10" size={150} />
          </div>

          {/* AI vs Self comparison — enhanced */}
          <div style={{ marginBottom: 18 }}>
            <div className="eyebrow mb-2" style={{ textAlign: 'center' }}>Score Comparison</div>
            <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 8, marginBottom: 10 }}>
              {/* AI */}
              <div style={{
                padding: '14px 12px', borderRadius: 10, textAlign: 'center',
                background: 'var(--accent-wash)', border: '2px solid var(--accent)',
              }}>
                <div className="eyebrow" style={{ fontSize: 9, color: 'var(--accent)', marginBottom: 4 }}>AI Evaluation</div>
                <div className="serif tnum" style={{ fontSize: 34, lineHeight: 1, color: 'var(--accent)', fontWeight: 700 }}>
                  {typeof r.scores.overall === 'number' ? r.scores.overall.toFixed(1) : r.scores.overall}
                </div>
                <div style={{ fontSize: 9.5, color: 'var(--ink-4)', marginTop: 2 }}>/10</div>
                <div style={{ marginTop: 8 }}>
                  <span className="pill pill-accent" style={{ fontSize: 10.5, fontWeight: 600 }}>{r.grade.g} · {r.grade.label}</span>
                </div>
              </div>
              {/* Self */}
              <div style={{
                padding: '14px 12px', borderRadius: 10, textAlign: 'center',
                background: 'var(--paper-2)', border: '2px solid var(--rule)',
              }}>
                <div className="eyebrow" style={{ fontSize: 9, color: 'var(--ink-3)', marginBottom: 4 }}>Self Assessment</div>
                <div className="serif tnum" style={{ fontSize: 34, lineHeight: 1, color: 'var(--ink-2)', fontWeight: 700 }}>
                  {typeof r.selfScore === 'number' ? r.selfScore.toFixed(1) : (r.selfScore || '—')}
                </div>
                <div style={{ fontSize: 9.5, color: 'var(--ink-4)', marginTop: 2 }}>/10</div>
                {(() => {
                  const diff  = parseFloat(r.selfScore) - parseFloat(r.scores.overall);
                  if (isNaN(diff)) return null;
                  const label = diff > 1.5 ? 'Overestimates' : diff < -1.5 ? 'Underestimates' : 'Accurate self-view';
                  const tone  = diff > 1.5 ? 'warn' : diff < -1.5 ? 'info' : 'ok';
                  return (
                    <div style={{ marginTop: 8 }}>
                      <span className={`pill pill-${tone}`} style={{ fontSize: 10, fontWeight: 500 }}>
                        {diff > 0 ? '+' : ''}{diff.toFixed(1)} · {label}
                      </span>
                    </div>
                  );
                })()}
              </div>
            </div>

            {/* Bar comparison row */}
            {(() => {
              const ai   = parseFloat(r.scores.overall) || 0;
              const self = parseFloat(r.selfScore)      || 0;
              return (
                <div style={{ background: 'var(--paper-2)', borderRadius: 8, padding: '12px 14px', marginBottom: 10 }}>
                  {[{ label: 'AI score',   val: ai,   color: 'var(--accent)' },
                    { label: 'Self score', val: self, color: 'var(--ink-3)' }]
                    .map(({ label, val, color }) => (
                    <div key={label} style={{ marginBottom: 8 }}>
                      <div style={{ display: 'flex', justifyContent: 'space-between', fontSize: 10.5, color: 'var(--ink-4)', marginBottom: 3 }}>
                        <span>{label}</span>
                        <span className="mono" style={{ color, fontWeight: 600 }}>{val.toFixed(1)} / 10</span>
                      </div>
                      <div style={{ height: 6, background: 'var(--rule)', borderRadius: 3, overflow: 'hidden' }}>
                        <div style={{ height: '100%', width: `${(val / 10) * 100}%`, background: color, borderRadius: 3, transition: 'width 1s ease' }}/>
                      </div>
                    </div>
                  ))}
                </div>
              );
            })()}

            {/* Verdict band — prominent */}
            <div style={{
              padding: '12px 14px', borderRadius: 8, border: `2px solid var(--${r.grade.tone})`,
              background: r.grade.tone === 'ok' ? 'var(--ok-wash)' : r.grade.tone === 'warn' ? 'var(--warn-wash)' : 'var(--bad-wash)',
            }}>
              <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 6 }}>
                <span style={{ fontSize: 20, lineHeight: 1 }}>
                  {r.grade.tone === 'ok' ? '✓' : r.grade.tone === 'warn' ? '△' : '✗'}
                </span>
                <div style={{ fontSize: 13, fontWeight: 700, color: `var(--${r.grade.tone})` }}>
                  {r.grade.label}
                </div>
                <span className="pill" style={{ marginLeft: 'auto', fontSize: 11, fontWeight: 600 }}>{r.grade.g}</span>
              </div>
              <div style={{ fontSize: 11.5, color: 'var(--ink-3)', lineHeight: 1.6 }}>
                {r.grade.tone === 'ok'
                  ? 'Performance is above the cohort benchmark. Strengths are consistent across dimensions.'
                  : r.grade.tone === 'warn'
                  ? 'Performance is approaching the benchmark. Targeted practice on weak dimensions will bridge the gap.'
                  : 'Performance is below benchmark. Coaching and structured practice are recommended before the next attempt.'}
              </div>
            </div>
          </div>

          <div className="eyebrow mb-3">Vs. cohort</div>
          <div style={{ display: 'grid', placeItems: 'center', marginBottom: 16 }}>
            <Radar axes={axes} values={critValues} compare={cohort} size={240} />
          </div>
          <div style={{ display: 'flex', justifyContent: 'center', gap: 16, fontSize: 10.5, color: 'var(--ink-4)' }}>
            <span style={{ display: 'flex', alignItems: 'center', gap: 5 }}>
              <span style={{ width: 10, height: 2, background: 'var(--accent)' }}/>This student
            </span>
            <span style={{ display: 'flex', alignItems: 'center', gap: 5 }}>
              <span style={{ width: 10, height: 2, background: 'var(--ink-4)', borderTop: '1px dashed' }}/>Cohort avg
            </span>
          </div>
        </div>
      </div>

      <div style={{ borderTop: '1px solid var(--rule)', marginTop: 28, paddingTop: 22 }}>
        <div className="eyebrow mb-3">Voice telemetry</div>
        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(5, 1fr)', gap: 10 }}>
          {[
            { k: 'Duration', v: `${Math.floor(r.duration / 60)}:${String(r.duration % 60).padStart(2,'0')}`, sub: 'mm:ss',  c: '--viz-2' },
            { k: 'Words',    v: r.words,                                                                  sub: 'total',   c: '--viz-4' },
            { k: 'Pace',     v: `${r.wpm}`,                                                                sub: 'wpm',     c: '--viz-1' },
            { k: 'Fillers',  v: r.fillers,                                                                 sub: '"um", "like"…', c: '--viz-5' },
            { k: 'Pause rate', v: r.pauseRate.toFixed(1),                                                  sub: 'per min', c: '--viz-3' },
          ].map((s, i) => (
            <div key={i} style={{ padding: '12px 14px', border: '1px solid var(--rule)', borderRadius: 'var(--radius-lg)', borderTop: `3px solid var(${s.c})` }}>
              <div className="eyebrow" style={{ color: `var(${s.c})` }}>{s.k}</div>
              <div className="serif tnum" style={{ fontSize: 26, marginTop: 3, color: 'var(--ink)' }}>{s.v}</div>
              <div style={{ fontSize: 10.5, color: 'var(--ink-4)', marginTop: 1 }}>{s.sub}</div>
            </div>
          ))}
        </div>
      </div>

      <CoachingSection r={r} />
      <TranscriptSection r={r} />
    </div>
  );
}

// ── Coaching — concrete, actionable improvements from content analysis ─
function CoachingSection({ r }) {
  const weakestKey = r.weakest_dimension || (() => {
    // fallback: compute from scores
    const entries = CRITERIA.map((c) => ({ key: c.key, val: r.scores[c.key] }));
    return entries.sort((a, b) => a.val - b.val)[0]?.key || 'clarity';
  })();
  const weakestCrit = CRITERIA.find((c) => c.key === weakestKey) || CRITERIA[2];
  const weakestVal  = r.scores[weakestKey] || 0;
  const colorIdx    = CRITERIA.findIndex((c) => c.key === weakestKey);

  // ── Annotated excerpts (real from AI, fallback empty) ─────────────────────
  const excerpts = r.annotated_excerpts || [];

  // ── Coaching drills (real from AI) ────────────────────────────────────────
  const drills = r.coaching_drills || [];

  // ── Content density (real from AI + local analysis) ───────────────────────
  const cd = r.content_density || {};

  // ── High-leverage lifts — computed from actual metrics ────────────────────
  const fillerRate = r.duration > 0 ? ((cd.fillers || r.fillers || 0) / (r.duration / 60)).toFixed(1) : (cd.fillers || r.fillers || 0);
  const targetWpm  = r.wpm < 130 ? 140 : r.wpm > 170 ? 155 : '145';
  const leverage = [
    { icon: '↓', metric: 'Fillers',     from: `${fillerRate}/min`,           to: '≤2/min',       lift: '+5 Delivery',  tone: 'viz-5' },
    { icon: '↑', metric: 'Pace',        from: `${r.wpm || '—'} wpm`,         to: `${targetWpm} wpm`, lift: '+3 Voice', tone: 'viz-1' },
    { icon: '↑', metric: 'Specificity', from: `${weakestVal}/100`,           to: '80/100',        lift: '+4 Content',   tone: 'viz-4' },
  ];

  const flagStyle = (kind) => ({
    background: kind === 'filler' ? '#fde2e2' : kind === 'hedge' ? '#fef3c7' : '#e0e7ff',
    color:      kind === 'filler' ? '#991b1b' : kind === 'hedge' ? '#92400e' : '#3730a3',
    borderBottom: '1.5px solid currentColor',
    padding: '0 2px', margin: '0 1px', borderRadius: '2px',
    fontWeight: 500,
  });

  return (
    <div style={{ borderTop: '1px solid var(--rule)', marginTop: 32, paddingTop: 28 }}>
      <div style={{ display: 'flex', alignItems: 'baseline', justifyContent: 'space-between', marginBottom: 18 }}>
        <div>
          <div className="eyebrow mb-2">Coaching — Suggested revisions</div>
          <h2 className="serif" style={{ fontSize: 28, letterSpacing: '-0.01em', lineHeight: 1.1 }}>
            How to take this from <em style={{ color: 'var(--accent)', fontStyle: 'italic' }}>{r.grade.g}</em> to <em style={{ fontStyle: 'italic' }}>the next grade up.</em>
          </h2>
          <div style={{ fontSize: 12.5, color: 'var(--ink-3)', marginTop: 6, maxWidth: '64ch' }}>
            Three changes, applied to the actual transcript, with the projected score lift each would produce.
          </div>
        </div>
        <button className="btn btn-sm"><Icon name="download" size={12}/> Drill plan</button>
      </div>

      {/* High-leverage lifts */}
      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 10, marginBottom: 24 }}>
        {leverage.map((l, i) => (
          <div key={i} className="fade-up" style={{
            animationDelay: `${i * 0.06}s`,
            padding: '14px 16px', border: '1px solid var(--rule)',
            borderRadius: 'var(--radius-lg)', background: 'var(--card)',
            display: 'flex', alignItems: 'center', gap: 14,
            borderLeft: `3px solid var(--${l.tone})`,
          }}>
            <div className="serif" style={{ fontSize: 32, color: `var(--${l.tone})`, lineHeight: 1 }}>{l.icon}</div>
            <div style={{ flex: 1 }}>
              <div className="eyebrow" style={{ color: `var(--${l.tone})` }}>{l.metric}</div>
              <div className="mono" style={{ fontSize: 12, color: 'var(--ink-2)', marginTop: 3 }}>
                <span style={{ color: 'var(--ink-4)' }}>{l.from}</span>
                <span style={{ margin: '0 6px' }}>→</span>
                <span style={{ color: 'var(--ink)', fontWeight: 500 }}>{l.to}</span>
              </div>
            </div>
            <div className="pill pill-accent mono" style={{ fontSize: 10 }}>{l.lift}</div>
          </div>
        ))}
      </div>

      {/* Annotated transcript excerpts */}
      {excerpts.length > 0 && (
        <>
          <div className="eyebrow mb-3">Annotated excerpts — <span style={{ textTransform: 'none', letterSpacing: 0, color: 'var(--ink-4)', fontStyle: 'italic' }}>problem passages, rewritten</span></div>
          <div style={{ display: 'flex', flexDirection: 'column', gap: 14, marginBottom: 28 }}>
            {excerpts.map((t, i) => {
              const tone = i === excerpts.length - 1 ? 'ok' : 'warn';
              // Build highlighted original
              const flags = t.highlights || [];
              let parts = [{ text: t.original || '', flag: null }];
              flags.forEach((f) => {
                parts = parts.flatMap((p) => {
                  if (p.flag || !f.text) return [p];
                  const idx = p.text.toLowerCase().indexOf(f.text.toLowerCase());
                  if (idx < 0) return [p];
                  return [
                    { text: p.text.slice(0, idx),               flag: null },
                    { text: p.text.slice(idx, idx + f.text.length), flag: f.kind },
                    { text: p.text.slice(idx + f.text.length),  flag: null },
                  ].filter((x) => x.text);
                });
              });
              return (
                <div key={i} className="fade-up" style={{
                  animationDelay: `${0.1 + i * 0.08}s`,
                  border: '1px solid var(--rule)', borderRadius: 'var(--radius-lg)',
                  overflow: 'hidden', background: 'var(--card)',
                }}>
                  <div style={{ display: 'grid', gridTemplateColumns: '110px 1fr', gap: 0, borderBottom: '1px solid var(--rule)' }}>
                    <div style={{
                      background: `var(--${tone}-wash)`, padding: '14px 14px',
                      display: 'flex', flexDirection: 'column', justifyContent: 'center',
                      borderRight: '1px solid var(--rule)',
                    }}>
                      <div className="eyebrow" style={{ color: `var(--${tone})` }}>{t.tag}</div>
                      <div className="mono" style={{ fontSize: 10, color: 'var(--ink-4)', marginTop: 4 }}>{t.timestamp || `${i}:00`}</div>
                    </div>
                    <div style={{ padding: '14px 18px' }}>
                      <div className="mono" style={{ fontSize: 9.5, letterSpacing: '.1em', textTransform: 'uppercase', color: 'var(--ink-4)', marginBottom: 6 }}>Original</div>
                      <div className="serif" style={{ fontSize: 15, lineHeight: 1.55, color: 'var(--ink-2)', fontStyle: 'italic' }}>
                        "{parts.map((p, j) => p.flag
                          ? <span key={j} style={flagStyle(p.flag)}>{p.text}</span>
                          : <span key={j}>{p.text}</span>)}"
                      </div>
                    </div>
                  </div>
                  <div style={{ display: 'grid', gridTemplateColumns: '110px 1fr', gap: 0 }}>
                    <div style={{ padding: '14px 14px', background: 'var(--ok-wash)', borderRight: '1px solid var(--rule)', display: 'flex', alignItems: 'center' }}>
                      <div className="eyebrow" style={{ color: 'var(--ok)' }}>✓ Rewrite</div>
                    </div>
                    <div style={{ padding: '14px 18px' }}>
                      <div className="serif" style={{ fontSize: 15, lineHeight: 1.55, color: 'var(--ink)', fontWeight: 500 }}>"{t.rewrite}"</div>
                      <div style={{ fontSize: 11.5, color: 'var(--ink-4)', marginTop: 8, lineHeight: 1.55, fontStyle: 'italic' }}>
                        <span style={{ color: 'var(--ink-3)', fontWeight: 500, fontStyle: 'normal' }}>Why: </span>{t.why}
                      </div>
                    </div>
                  </div>
                </div>
              );
            })}
          </div>
        </>
      )}

      {/* Legend + drills */}
      <div style={{ display: 'grid', gridTemplateColumns: '1fr 1.4fr', gap: 18 }}>
        <div style={{ padding: '16px 18px', border: '1px solid var(--rule)', borderRadius: 'var(--radius-lg)', background: 'var(--card-2)' }}>
          <div className="eyebrow mb-3">Highlight legend</div>
          <div style={{ display: 'flex', flexDirection: 'column', gap: 8, fontSize: 12 }}>
            <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
              <span style={flagStyle('filler')}>fillers</span>
              <span style={{ color: 'var(--ink-3)' }}>
                {cd.filler_words?.length ? `"${cd.filler_words.slice(0,3).join('", "')}"` : '"um", "like"'} — remove entirely
              </span>
            </div>
            <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
              <span style={flagStyle('hedge')}>hedges</span>
              <span style={{ color: 'var(--ink-3)' }}>
                {cd.hedge_words?.length ? `"${cd.hedge_words.slice(0,3).join('", "')}"` : '"kind of", "I think"'} — weaken claims
              </span>
            </div>
            <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
              <span style={flagStyle('vague')}>vague</span>
              <span style={{ color: 'var(--ink-3)' }}>
                {cd.vague_phrases?.length ? `"${cd.vague_phrases.slice(0,2).join('", "')}"` : '"a lot of", "this thing"'} — replace with evidence
              </span>
            </div>
          </div>
          <hr className="rule" style={{ margin: '14px 0' }}/>
          <div className="eyebrow mb-2">Content density</div>
          <div style={{ fontSize: 12, lineHeight: 1.6, color: 'var(--ink-3)' }}>
            <span className="serif tnum" style={{ fontSize: 24, color: 'var(--ink)' }}>{cd.fillers ?? r.fillers ?? 0}</span>
            <span className="mono" style={{ fontSize: 10, color: 'var(--ink-4)', marginLeft: 4 }}>FILLERS</span>
            <span style={{ margin: '0 10px', color: 'var(--ink-5)' }}>·</span>
            <span className="serif tnum" style={{ fontSize: 24, color: 'var(--ink)' }}>{cd.hedges ?? 0}</span>
            <span className="mono" style={{ fontSize: 10, color: 'var(--ink-4)', marginLeft: 4 }}>HEDGES</span>
            <span style={{ margin: '0 10px', color: 'var(--ink-5)' }}>·</span>
            <span className="serif tnum" style={{ fontSize: 24, color: 'var(--ink)' }}>{cd.vague ?? 0}</span>
            <span className="mono" style={{ fontSize: 10, color: 'var(--ink-4)', marginLeft: 4 }}>VAGUE</span>
          </div>
          <div style={{ fontSize: 11, color: 'var(--ink-4)', marginTop: 8, fontStyle: 'italic' }}>
            Detected across {r.words} words of transcript.
          </div>
        </div>

        {drills.length > 0 && (
          <div>
            <div className="eyebrow mb-3">
              Drills for <span style={{ color: `var(${CRIT_COLOR[colorIdx] || '--accent'})`, textTransform: 'none', letterSpacing: 0, fontStyle: 'italic' }}>
                {weakestCrit.label.toLowerCase()}
              </span> — your weakest dimension ({weakestVal}/100)
            </div>
            <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
              {drills.map((d, i) => (
                <div key={i} className="fade-up" style={{
                  animationDelay: `${0.14 + i * 0.06}s`,
                  padding: '14px 16px', background: 'var(--card)',
                  border: '1px solid var(--rule)', borderRadius: 'var(--radius-lg)',
                  display: 'grid', gridTemplateColumns: '28px 1fr', gap: 12, alignItems: 'start',
                }}>
                  <div className="serif tnum" style={{ fontSize: 22, color: `var(${CRIT_COLOR[colorIdx] || '--accent'})`, lineHeight: 1 }}>
                    {String(i + 1).padStart(2, '0')}
                  </div>
                  <div>
                    <div style={{ fontSize: 13, fontWeight: 600, color: 'var(--ink)', marginBottom: 3 }}>{d.title || d.t}</div>
                    <div style={{ fontSize: 12, lineHeight: 1.55, color: 'var(--ink-3)' }}>{d.description || d.d}</div>
                  </div>
                </div>
              ))}
            </div>
          </div>
        )}
      </div>
    </div>
  );
}


// ── Transcript section ────────────────────────────────────
function TranscriptSection({ r }) {
  const [open,   setOpen]   = React.useState(true);   // open by default so it appears in PDF
  const [copied, setCopied] = React.useState(false);

  const raw = (r.transcript || '').trim();
  if (!raw) return null;

  // Build filler/hedge/vague word sets from content_density
  const cd = r.content_density || {};
  const fillerSet = new Set((cd.filler_words  || []).map((w) => w.toLowerCase()));
  const hedgeSet  = new Set((cd.hedge_words   || []).map((w) => w.toLowerCase()));
  const vagueSet  = new Set((cd.vague_phrases || []).map((w) => w.toLowerCase()));

  // Tokenise preserving whitespace / punctuation for highlighting
  const tokens = raw.split(/(\s+)/);

  const getHighlight = (tok) => {
    const clean = tok.replace(/[^a-zA-Z]/g, '').toLowerCase();
    if (fillerSet.has(clean)) return { bg: '#fde2e2', color: '#991b1b', title: 'Filler word' };
    if (hedgeSet.has(clean))  return { bg: '#fef3c7', color: '#92400e', title: 'Hedge word' };
    if (vagueSet.has(clean))  return { bg: '#e0e7ff', color: '#3730a3', title: 'Vague word' };
    return null;
  };

  const handleCopy = () => {
    navigator.clipboard.writeText(raw).then(() => {
      setCopied(true);
      setTimeout(() => setCopied(false), 2000);
    });
  };

  // Split into paragraphs on double newline, or wrap at ~80 words per paragraph
  const paragraphs = raw.includes('\n')
    ? raw.split(/\n{2,}/).filter(Boolean)
    : (() => {
        const words = raw.split(' ');
        const chunks = [];
        for (let i = 0; i < words.length; i += 80) chunks.push(words.slice(i, i + 80).join(' '));
        return chunks;
      })();

  const wordCount = raw.split(/\s+/).filter(Boolean).length;
  const charCount = raw.length;

  return (
    <div style={{ borderTop: '2px solid var(--rule)', marginTop: 36 }}>

      {/* Section header — clickable to collapse */}
      <div style={{
        display: 'flex', alignItems: 'center', gap: 12,
        padding: '20px 0 16px', cursor: 'pointer', userSelect: 'none',
      }} onClick={() => setOpen((o) => !o)}>
        <div style={{
          width: 36, height: 36, borderRadius: 8, flexShrink: 0,
          background: 'var(--ink)', color: 'var(--paper)',
          display: 'grid', placeItems: 'center',
        }}>
          <Icon name="mic" size={16} />
        </div>
        <div style={{ flex: 1 }}>
          <div className="eyebrow mb-1" style={{ fontSize: 9.5 }}>Audio to Text · Speech Recognition</div>
          <div style={{ fontSize: 16, fontWeight: 600, fontFamily: 'var(--f-display)', letterSpacing: '-0.01em' }}>
            Full Speech Transcript
          </div>
          <div style={{ fontSize: 11.5, color: 'var(--ink-4)', marginTop: 2 }}>
            {wordCount.toLocaleString()} words · {charCount.toLocaleString()} chars
            {fillerSet.size + hedgeSet.size + vagueSet.size > 0 && ' · annotated'}
          </div>
        </div>

        {open && (fillerSet.size > 0 || hedgeSet.size > 0 || vagueSet.size > 0) && (
          <div style={{ display: 'flex', gap: 6, fontSize: 10.5 }}>
            {fillerSet.size > 0 && <span style={{ background: '#fde2e2', color: '#991b1b', padding: '2px 8px', borderRadius: 4, fontWeight: 500 }}>filler</span>}
            {hedgeSet.size > 0 && <span style={{ background: '#fef3c7', color: '#92400e', padding: '2px 8px', borderRadius: 4, fontWeight: 500 }}>hedge</span>}
            {vagueSet.size > 0 && <span style={{ background: '#e0e7ff', color: '#3730a3', padding: '2px 8px', borderRadius: 4, fontWeight: 500 }}>vague</span>}
          </div>
        )}

        <button
          className="btn btn-ghost btn-sm print-hide"
          onClick={(e) => { e.stopPropagation(); handleCopy(); }}
          style={{ padding: '4px 10px', fontSize: 11 }}
          title="Copy transcript to clipboard"
        >
          <Icon name={copied ? 'check' : 'copy'} size={12} />
          {copied ? ' Copied' : ' Copy'}
        </button>

        <Icon name="chevron" size={14} style={{
          transform: open ? 'rotate(180deg)' : 'none',
          transition: 'transform .2s', color: 'var(--ink-4)', flexShrink: 0,
        }} />
      </div>

      {/* Transcript body */}
      {open && (
        <div className="fade-in" style={{
          background: 'var(--paper-2)',
          border: '1px solid var(--rule)',
          borderRadius: 'var(--radius-lg)',
          overflow: 'hidden',
          marginBottom: 32,
        }}>
          {/* Dark sub-header */}
          <div style={{
            padding: '10px 20px', background: 'var(--ink)', color: 'var(--paper)',
            display: 'flex', alignItems: 'center', gap: 10, fontSize: 11,
          }}>
            <Icon name="mic" size={12} style={{ opacity: 0.7 }} />
            <span style={{ opacity: 0.7 }}>Recorded speech · automatically transcribed</span>
            <span style={{ marginLeft: 'auto', fontFamily: 'var(--f-mono)', opacity: 0.55, fontSize: 10 }}>
              {wordCount.toLocaleString()} words
            </span>
          </div>

          {/* Text paragraphs */}
          <div style={{ padding: '24px 28px' }}>
            {paragraphs.map((para, pi) => {
              const paraTokens = para.split(/(\s+)/);
              return (
                <p key={pi} style={{
                  fontSize: 14, lineHeight: 2,
                  color: 'var(--ink-2)', fontFamily: 'var(--f-body)',
                  marginBottom: pi < paragraphs.length - 1 ? '1.4em' : 0,
                }}>
                  {paraTokens.map((tok, ti) => {
                    if (/^\s+$/.test(tok)) return tok;
                    const hl = getHighlight(tok);
                    return hl ? (
                      <span key={ti} title={hl.title} style={{
                        background: hl.bg, color: hl.color,
                        borderRadius: 3, padding: '0 2px',
                        fontWeight: 500, cursor: 'help',
                      }}>{tok}</span>
                    ) : tok;
                  })}
                </p>
              );
            })}
          </div>

          {/* Stats footer */}
          <div style={{
            display: 'flex', gap: 24, flexWrap: 'wrap',
            padding: '12px 28px 14px',
            borderTop: '1px solid var(--rule)',
            background: 'var(--paper-3)',
            fontSize: 11.5, color: 'var(--ink-4)',
          }}>
            {[
              { k: 'Words',    v: wordCount.toLocaleString() },
              { k: 'Pace',     v: `${r.wpm || '—'} wpm` },
              { k: 'Duration', v: `${Math.floor((r.duration || 0) / 60)}:${String((r.duration || 0) % 60).padStart(2, '0')}` },
              { k: 'Fillers',  v: cd.fillers ?? r.fillers ?? 0 },
              { k: 'Hedges',   v: cd.hedges  ?? 0 },
            ].map((s) => (
              <span key={s.k}>
                <span className="mono" style={{ color: 'var(--ink-2)', fontWeight: 600 }}>{s.v}</span>
                {' '}{s.k.toLowerCase()}
              </span>
            ))}
          </div>
        </div>
      )}
      <ReportFooter />
    </div>
  );
}

// ── Dashboard layout (widgety) ────────────────────────────
function ReportDashboard({ r, head, cohort, critValues, axes }) {
  return (
    <div className="fade-up">
      {head}
      <div style={{ display: 'grid', gridTemplateColumns: '260px 1fr 1fr', gap: 14 }}>
        <div className="card card-pad" style={{ display: 'grid', placeItems: 'center' }}>
          <ScoreRing value={r.scores.overall} size={160} />
          <div className="mt-3" style={{ textAlign: 'center' }}>
            <span className="pill pill-accent">{r.grade.g} · {r.grade.label}</span>
          </div>
        </div>
        <div className="card">
          <div className="card-hd"><span className="card-title">Criteria breakdown</span></div>
          <div className="card-pad">
            {CRITERIA.map((c) => (
              <BarRow key={c.key} label={c.label} value={r.scores[c.key]} right={r.scores[c.key]} />
            ))}
          </div>
        </div>
        <div className="card">
          <div className="card-hd"><span className="card-title">Vs. cohort</span></div>
          <div className="card-pad" style={{ display: 'grid', placeItems: 'center' }}>
            <Radar axes={axes} values={critValues} compare={cohort} size={220} />
          </div>
        </div>
      </div>
      <div style={{ display: 'grid', gridTemplateColumns: '1.3fr 1fr', gap: 14, marginTop: 14 }}>
        <div className="card card-pad">
          <div className="eyebrow mb-2">Verdict</div>
          <div style={{ fontSize: 13.5, lineHeight: 1.7, color: 'var(--ink-2)' }}>{r.verdict}</div>
          <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 18, marginTop: 16 }}>
            <div>
              <div className="eyebrow mb-2" style={{ color: 'var(--ok)' }}>Strengths</div>
              {r.strengths.map((s, i) => <div key={i} style={{ fontSize: 12, color: 'var(--ink-2)', marginBottom: 4 }}>+ {s}</div>)}
            </div>
            <div>
              <div className="eyebrow mb-2" style={{ color: 'var(--bad)' }}>To improve</div>
              {r.weaknesses.map((s, i) => <div key={i} style={{ fontSize: 12, color: 'var(--ink-2)', marginBottom: 4 }}>− {s}</div>)}
            </div>
          </div>
        </div>
        <div className="card card-pad">
          <div className="eyebrow mb-3">Telemetry</div>
          <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 14 }}>
            {[
              { k: 'Duration',    v: `${Math.floor(r.duration / 60)}:${String(r.duration % 60).padStart(2,'0')}` },
              { k: 'Words',       v: r.words },
              { k: 'Pace (wpm)',  v: r.wpm },
              { k: 'Fillers',     v: r.fillers },
              { k: 'Pause/min',   v: r.pauseRate.toFixed(1) },
              { k: 'Self-score',  v: r.selfScore },
            ].map((s, i) => (
              <div key={i}>
                <div className="eyebrow">{s.k}</div>
                <div className="serif" style={{ fontSize: 24 }}>{s.v}</div>
              </div>
            ))}
          </div>
        </div>
      </div>
    </div>
  );
}

// ── Briefing (compact one-pager) ───────────────────────────
function ReportBriefing({ r, head, cohort, critValues, axes }) {
  return (
    <div className="fade-up">
      {head}
      <div className="card card-pad" style={{ display: 'grid', gridTemplateColumns: '140px 1fr 240px', gap: 22, alignItems: 'center' }}>
        <ScoreRing value={r.scores.overall} size={120} />
        <div>
          <div className="eyebrow mb-1">Verdict</div>
          <div className="serif" style={{ fontSize: 18, lineHeight: 1.4, fontStyle: 'italic', color: 'var(--ink-2)' }}>{r.verdict}</div>
          <div className="mt-3" style={{ display: 'flex', gap: 10, fontSize: 11, color: 'var(--ink-4)' }}>
            <span>{r.duration}s</span><span>·</span>
            <span>{r.words} words</span><span>·</span>
            <span>{r.wpm} wpm</span><span>·</span>
            <span>{r.fillers} fillers</span>
          </div>
        </div>
        <Radar axes={axes} values={critValues} compare={cohort} size={220} />
      </div>
      <div className="mt-4" style={{ display: 'grid', gridTemplateColumns: 'repeat(6, 1fr)', gap: 10 }}>
        {CRITERIA.map((c) => {
          const v = r.scores[c.key];
          return (
            <div key={c.key} className="card card-pad">
              <div className="eyebrow">{c.label}</div>
              <div className="serif tnum" style={{ fontSize: 28, marginTop: 4 }}>{v}</div>
              <div style={{ height: 3, background: 'var(--rule)', marginTop: 6 }}>
                <div style={{ height: '100%', width: `${v}%`, background: 'var(--accent)', transition: 'width 1s' }} />
              </div>
            </div>
          );
        })}
      </div>
    </div>
  );
}

Object.assign(window, { ReportView });
