/* ============================================================
   MUIY — Doctor Report feature (JSX)
   · MonReportConfigSheet — scope + date range, then Generate
   · MonReportOverlay     — full-screen clinical preview (mobile)
   · ReportPrintDoc        — A4 print document (portal → body),
                             shown only by the print stylesheet
   Reads the computed model from window.TCReport.build().
   ============================================================ */

/* ---- shared status palette for tables ---- */
function repStatus(status) {
  return MON.STATUS_META[status] || MON.STATUS_META.OPTIONAL;
}

/* ---- clean line chart (screen + print; pure SVG, scales by viewBox) ---- */
function RepChart({ data, color = '#2E6E73', band, unit, height = 150, print }) {
  const pts = (data || []).filter((p) => p.value != null);
  if (pts.length < 2) {
    return <div style={{ fontSize: print ? '8.5pt' : 12, color: print ? '#9aabab' : 'var(--ink-3)', padding: print ? '6pt 0' : '8px 0' }}>Not enough data points in this period.</div>;
  }
  const W = 520, H = 170, padL = 42, padR = 14, padT = 14, padB = 26;
  const vals = pts.map((p) => p.value);
  let dmin = Math.min(...vals), dmax = Math.max(...vals);
  if (band) { if (band.low != null) dmin = Math.min(dmin, band.low); if (band.high != null) dmax = Math.max(dmax, band.high); }
  const span = (dmax - dmin) || Math.abs(dmax) || 1;
  let min = dmin - span * 0.16, max = dmax + span * 0.16;
  if (min === max) { min -= 1; max += 1; }
  const x = (i) => padL + (i / (pts.length - 1)) * (W - padL - padR);
  const y = (v) => padT + (1 - (v - min) / (max - min)) * (H - padT - padB);
  const line = pts.map((p, i) => `${i ? 'L' : 'M'} ${x(i).toFixed(1)} ${y(p.value).toFixed(1)}`).join(' ');
  const area = `${line} L ${x(pts.length - 1).toFixed(1)} ${(H - padB).toFixed(1)} L ${x(0).toFixed(1)} ${(H - padB).toFixed(1)} Z`;
  const ticks = [max, (min + max) / 2, min];
  const fmt = (v) => Math.abs(v) >= 1000 ? (v / 1000).toFixed(1) + 'k' : (Math.round(v * 10) / 10);
  const bandTop = band && band.high != null ? y(Math.min(band.high, max)) : padT;
  const bandBot = band && band.low != null ? y(Math.max(band.low, min)) : (H - padB);
  const gid = 'rg' + Math.random().toString(36).slice(2, 7);
  // label every Nth date so the axis isn't crowded
  const step = Math.ceil(pts.length / 5);
  // On-screen the chart sits on a themed card, so axes/markers follow the
  // active theme; the printed PDF keeps fixed "paper" colours.
  const cGrid = print ? '#dfeaea' : 'var(--hairline)';
  const cAxis = print ? '#9aabab' : 'var(--ink-3)';
  const cDot  = print ? '#fff' : 'var(--surface)';
  const cBand = print ? '#4d8a13' : 'var(--success)';
  return (
    <svg viewBox={`0 0 ${W} ${H}`} width="100%" style={{ display: 'block' }}>
      <defs>
        <linearGradient id={gid} x1="0" y1="0" x2="0" y2="1">
          <stop offset="0" stopColor={color} stopOpacity={print ? '0.12' : '0.16'} />
          <stop offset="1" stopColor={color} stopOpacity="0" />
        </linearGradient>
      </defs>
      {band && (band.low != null || band.high != null) &&
        <rect x={padL} y={bandTop} width={W - padL - padR} height={Math.max(0, bandBot - bandTop)} fill={cBand} opacity="0.10" />}
      {ticks.map((tv, i) => (
        <g key={i}>
          <line x1={padL} y1={y(tv)} x2={W - padR} y2={y(tv)} stroke={cGrid} strokeWidth="1" />
          <text x={padL - 6} y={y(tv) + 3} fontSize="9" fontWeight="700" textAnchor="end" fill={cAxis}>{fmt(tv)}</text>
        </g>
      ))}
      <path d={area} fill={`url(#${gid})`} />
      <path d={line} fill="none" stroke={color} strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round" />
      {pts.map((p, i) => <circle key={i} cx={x(i)} cy={y(p.value)} r="3.1" fill={cDot} stroke={color} strokeWidth="2" />)}
      {pts.map((p, i) => (i % step === 0 || i === pts.length - 1)
        ? <text key={'t' + i} x={x(i)} y={H - 8} fontSize="8.5" fontWeight="700" textAnchor="middle" fill={cAxis}>{TC.fmtDate(p.date, { day: 'numeric', month: 'short' })}</text>
        : null)}
    </svg>
  );
}

/* ============================================================
   CONFIG SHEET — scope + date range, then generate.
   ============================================================ */
function MonReportConfigSheet({ store, close, onGenerate }) {
  const [scope, setScope] = React.useState('full');
  const [range, setRange] = React.useState('12m');
  const [from, setFrom] = React.useState(TC.daysAgoDate(365));
  const [to, setTo] = React.useState(TC.daysAgoDate(0));

  const opts = () => {
    if (range === 'all') return { from: null, to: null, rangeKey: 'all', scope };
    if (range === '12m') return { from: TC.daysAgoDate(365), to: TC.daysAgoDate(0), rangeKey: '12m', scope };
    return { from, to, rangeKey: 'custom', scope };
  };

  const SCOPES = [
    { k: 'full', t: 'Full medical summary', d: 'Everything — identity, therapy, transfusions, monitoring, trends.' },
    { k: 'monitoring', t: 'Monitoring only', d: 'Lab results table, outstanding tests and trend charts.' },
    { k: 'transfusion', t: 'Transfusion history only', d: 'Transfusion record, interval and next-due forecast.' },
  ];
  const RANGES = [
    { k: 'all', t: 'All time' },
    { k: '12m', t: 'Last 12 months' },
    { k: 'custom', t: 'Custom range' },
  ];

  return (
    <MSheet title="Doctor report" sub="Generate a clinical summary to share with your haematologist or care team." onClose={close}>
      <div className="card-flat row" style={{ padding: '11px 14px', gap: 10, marginBottom: 16 }}>
        <Icon name="clipboard" size={16} color="var(--sky-deep)" style={{ flex: 'none' }} />
        <span className="body" style={{ fontSize: 12.3, lineHeight: 1.45 }}>A professional, print-ready summary built from your own records. Review it on screen, then save or print as a PDF.</span>
      </div>

      <SLabel>What to include</SLabel>
      <div style={{ display: 'flex', flexDirection: 'column', gap: 9, marginBottom: 18 }}>
        {SCOPES.map((s) => {
          const on = scope === s.k;
          return (
            <button key={s.k} className="card-flat" onClick={() => setScope(s.k)}
              style={{ display: 'flex', gap: 11, alignItems: 'flex-start', textAlign: 'left', cursor: 'pointer', fontFamily: 'inherit', padding: '12px 13px', border: `1.5px solid ${on ? 'var(--sky-deep)' : 'var(--hairline)'}`, background: on ? 'var(--sky-wash)' : 'var(--surface)' }}>
              <span style={{ width: 19, height: 19, flex: 'none', borderRadius: 999, border: `2px solid ${on ? 'var(--sky-deep)' : 'var(--hairline-2)'}`, background: on ? 'var(--sky-deep)' : 'transparent', display: 'grid', placeItems: 'center', marginTop: 1 }}>{on && <Icon name="check" size={11} color="#fff" sw={3} />}</span>
              <span style={{ flex: 1, minWidth: 0 }}>
                <span style={{ display: 'block', fontWeight: 800, fontSize: 13.5, color: 'var(--ink)' }}>{s.t}</span>
                <span style={{ display: 'block', fontSize: 11.5, color: 'var(--ink-2)', lineHeight: 1.45, marginTop: 2 }}>{s.d}</span>
              </span>
            </button>
          );
        })}
      </div>

      <SLabel>Time period</SLabel>
      <div className="seg" style={{ marginTop: 8, marginBottom: range === 'custom' ? 12 : 18 }}>
        {RANGES.map((r) => <button key={r.k} className={range === r.k ? 'on' : ''} onClick={() => setRange(r.k)} style={{ fontSize: 12.5 }}>{r.t}</button>)}
      </div>
      {range === 'custom' && (
        <div className="row" style={{ gap: 10, marginBottom: 18 }}>
          <div className="field" style={{ flex: 1, margin: 0 }}><label className="field-label">From</label><input className="input" type="date" value={from} max={to} onChange={(e) => setFrom(e.target.value)} /></div>
          <div className="field" style={{ flex: 1, margin: 0 }}><label className="field-label">To</label><input className="input" type="date" value={to} min={from} onChange={(e) => setTo(e.target.value)} /></div>
        </div>
      )}

      <button className="btn btn-primary" style={{ width: '100%', gap: 8 }} onClick={() => { onGenerate(opts()); }}>
        <Icon name="clipboard" size={17} color="#fff" /> Generate report
      </button>
    </MSheet>
  );
}

/* ============================================================
   ON-SCREEN PREVIEW (mobile) + print document.
   ============================================================ */
function repStatusChip(status, print) {
  const m = repStatus(status);
  if (print) return <span className="rp-tag" style={{ background: m.wash, color: m.color }}>{m.label}</span>;
  return <span className="rep-st" style={{ background: m.wash, color: m.color }}><span className="d" style={{ background: m.color }} />{m.label}</span>;
}

function repFmtRange(m) {
  if (m.window.key === 'all') return 'All time';
  if (m.window.key === '12m') return 'Last 12 months';
  return `${TC.fmtDate(m.window.from)} – ${TC.fmtDate(m.window.to)}`;
}

function MonReportOverlay({ store, model, onClose }) {
  const m = model;
  const showMon = m.scope === 'full' || m.scope === 'monitoring';
  const showTx = m.scope === 'full' || m.scope === 'transfusion';
  const showId = true;
  const fer = MON.testById('ferritin');
  const ferBand = fer && fer.normal_range ? fer.normal_range : null;
  const hbBand = (window.CLINICAL && CLINICAL.therapyBand) ? CLINICAL.therapyBand('haemoglobin', m.patient.thalShort) : null;

  const doPrint = () => { try { window.print(); } catch (e) {} };

  let secN = 0; const N = () => String(++secN).padStart(2, '0');

  return (
    <div className="mon-page">
      <div className="mon-page-head">
        <button className="mon-back" onClick={onClose} aria-label="Back"><Icon name="chevL" size={20} color="var(--ink)" /></button>
        <div className="ttl">Doctor report</div>
        <button className="chip" onClick={doPrint} style={{ background: 'var(--orange)', borderColor: 'transparent', color: '#fff', fontWeight: 800, fontSize: 12.5, padding: '8px 13px', gap: 6 }}><Icon name="download" size={15} color="#fff" />Save PDF</button>
      </div>

      <div className="mon-page-body">
        {/* letterhead + identity */}
        <div className="rep-band">
          <div className="rep-letterhead">
            <div className="brand"><Icon name="drop" size={15} color="#fff" fill="#fff" />MUIY · Clinical Summary</div>
            <h2>{m.patient.name}</h2>
            <div className="meta">{repFmtRange(m)} · Generated {TC.fmtDate(m.generatedAt)}</div>
          </div>
          {showId && (
            <div className="rep-id">
              <div className="f"><div className="k">Date of birth</div><div className="v">{m.patient.dob ? TC.fmtDate(m.patient.dob) : '—'}{m.patient.age != null ? ` · ${m.patient.age}y` : ''}</div></div>
              <div className="f"><div className="k">Blood group</div><div className="v">{m.patient.bloodGroup}</div></div>
              <div className="f"><div className="k">Diagnosis</div><div className="v" style={{ fontSize: 12.5 }}>{m.patient.thalType}</div></div>
              <div className="f"><div className="k">Status</div><div className="v">{m.patient.thalShort}{m.medical.splenectomy ? ' · Splenectomised' : ''}</div></div>
            </div>
          )}
        </div>

        {/* medical summary */}
        {m.scope === 'full' && (
          <div className="rep-sec">
            <div className="rep-sec-h"><span className="num">{N()}</span>Medical summary</div>
            <div className="card-flat" style={{ padding: '13px 15px' }}>
              <div className="rep-kvm"><b>Current chelation</b></div>
              {m.medical.chelation.length ? m.medical.chelation.map((c, i) => (
                <div key={i} className="between" style={{ padding: '7px 0', borderTop: i ? '1px solid var(--hairline)' : 'none', gap: 10 }}>
                  <span style={{ fontWeight: 700, fontSize: 13 }}>{c.name}{c.brand && c.brand !== c.name ? ` (${c.brand})` : ''}</span>
                  <span className="body" style={{ fontSize: 12, textAlign: 'right' }}>{c.dose} · {c.freq}</span>
                </div>
              )) : <div className="body" style={{ fontSize: 12.5, padding: '6px 0' }}>No chelation therapy on record.</div>}
              <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '10px 14px', marginTop: 12, paddingTop: 12, borderTop: '1px solid var(--hairline)' }}>
                <div><div className="eyebrow" style={{ marginBottom: 2 }}>Splenectomy</div><div style={{ fontWeight: 800, fontSize: 13 }}>{m.medical.splenectomy ? 'Yes' : 'No'}</div></div>
                <div><div className="eyebrow" style={{ marginBottom: 2 }}>Transfusion interval</div><div style={{ fontWeight: 800, fontSize: 13 }}>{m.medical.transfusionInterval || (m.transfusion.cadence ? `~${m.transfusion.cadence.weeks} wks` : '—')}</div></div>
              </div>
            </div>
          </div>
        )}

        {/* transfusion summary */}
        {showTx && (
          <div className="rep-sec">
            <div className="rep-sec-h"><span className="num">{N()}</span>Transfusion summary</div>
            <div className="card-flat" style={{ padding: '13px 15px', marginBottom: 10 }}>
              <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '11px 14px' }}>
                <div><div className="eyebrow" style={{ marginBottom: 2 }}>In period</div><div style={{ fontWeight: 800, fontSize: 15 }}>{m.transfusion.count}<span className="body" style={{ fontSize: 11 }}> sessions</span></div></div>
                <div><div className="eyebrow" style={{ marginBottom: 2 }}>Average interval</div><div style={{ fontWeight: 800, fontSize: 15 }}>{m.transfusion.cadence ? `${m.transfusion.cadence.weeks}` : '—'}<span className="body" style={{ fontSize: 11 }}> {m.transfusion.cadence ? 'weeks' : ''}</span></div></div>
                <div><div className="eyebrow" style={{ marginBottom: 2 }}>Regularity</div><div style={{ fontWeight: 800, fontSize: 13 }}>{m.transfusion.cadence ? m.transfusion.cadence.regular : '—'}</div></div>
                <div><div className="eyebrow" style={{ marginBottom: 2 }}>Last transfusion</div><div style={{ fontWeight: 800, fontSize: 13 }}>{m.transfusion.last ? TC.fmtDate(m.transfusion.last.date) : '—'}</div></div>
              </div>
              {m.transfusion.forecast && (
                <div className="row" style={{ gap: 9, marginTop: 12, padding: '10px 12px', background: 'var(--sky-wash)', borderRadius: 12 }}>
                  <Icon name="calendar" size={15} color="var(--sky-deep)" style={{ flex: 'none' }} />
                  <span className="body" style={{ fontSize: 12, color: 'var(--ink)' }}>Next transfusion forecast around <b>{TC.fmtDate(m.transfusion.forecast.date)}</b>{m.transfusion.forecast.daysUntil >= 0 ? ` (in ${m.transfusion.forecast.daysUntil}d)` : ''}.</span>
                </div>
              )}
            </div>
            {m.transfusion.recent.length > 0 && (
              <table className="rep-table">
                <thead><tr><th>Date</th><th>Units</th><th>Volume</th><th>Reaction</th></tr></thead>
                <tbody>
                  {m.transfusion.recent.map((t, i) => (
                    <tr key={i}><td>{TC.fmtDate(t.date)}</td><td className="val">{t.units || '—'}</td><td>{t.volumeMl ? `${t.volumeMl} mL` : '—'}</td><td>{t.reaction ? (t.reactionTypes || []).join(', ') || 'Yes' : 'None'}</td></tr>
                  ))}
                </tbody>
              </table>
            )}
          </div>
        )}

        {/* Hb trend (transfusion or full) */}
        {showTx && m.trends.haemoglobin.length >= 2 && (
          <div className="rep-sec">
            <div className="rep-sec-h"><span className="num">{N()}</span>Haemoglobin trend</div>
            <div className="card-flat" style={{ padding: '12px 12px 6px' }}><RepChart data={m.trends.haemoglobin} color="#E5484D" band={hbBand} unit="g/dL" /></div>
          </div>
        )}

        {/* monitoring table */}
        {showMon && (
          <div className="rep-sec">
            <div className="rep-sec-h"><span className="num">{N()}</span>Monitoring summary</div>
            <table className="rep-table">
              <thead><tr><th>Test</th><th>Latest</th><th>Date</th><th>Status</th></tr></thead>
              <tbody>
                {m.monitoring.map((p) => (
                  <React.Fragment key={p.key}>
                    <tr className="grp"><td colSpan={4}>{p.label}</td></tr>
                    {p.rows.map((r) => (
                      <tr key={r.id}>
                        <td>{r.name}</td>
                        <td className="val" style={{ color: r.abnormal ? r.flag.color : 'var(--ink)' }}>{r.value != null ? `${r.value}${r.unit ? ' ' + r.unit : ''}` : '—'}</td>
                        <td style={{ color: 'var(--ink-3)' }}>{r.date ? TC.fmtDate(r.date, { day: 'numeric', month: 'short', year: '2-digit' }) : '—'}</td>
                        <td>{repStatusChip(r.status)}</td>
                      </tr>
                    ))}
                  </React.Fragment>
                ))}
              </tbody>
            </table>
          </div>
        )}

        {/* ferritin trend */}
        {showMon && m.trends.ferritin.length >= 2 && (
          <div className="rep-sec">
            <div className="rep-sec-h"><span className="num">{N()}</span>Serum ferritin trend</div>
            <div className="card-flat" style={{ padding: '12px 12px 6px' }}><RepChart data={m.trends.ferritin} color="#FC6B05" band={ferBand} unit="ng/mL" /></div>
          </div>
        )}

        {/* outstanding monitoring */}
        {showMon && (m.outstanding.overdue.length + m.outstanding.dueSoon.length + m.outstanding.missing.length > 0) && (
          <div className="rep-sec">
            <div className="rep-sec-h"><span className="num">{N()}</span>Outstanding monitoring</div>
            <div className="card-flat" style={{ padding: '6px 14px' }}>
              {[['Overdue', m.outstanding.overdue, '#E5484D'], ['Due soon', m.outstanding.dueSoon, '#D98300'], ['Not yet recorded', m.outstanding.missing, '#5C7A80']].map(([label, rows, color]) => rows.length ? (
                <div key={label} style={{ padding: '9px 0', borderTop: '1px solid var(--hairline)' }}>
                  <div className="row" style={{ gap: 7, marginBottom: 6 }}><span style={{ width: 8, height: 8, borderRadius: 999, background: color }} /><span style={{ fontWeight: 800, fontSize: 12.5, color }}>{label}</span><span className="dmeta muted" style={{ marginLeft: 'auto' }}>{rows.length}</span></div>
                  <div style={{ fontSize: 12.5, color: 'var(--ink-2)', lineHeight: 1.55 }}>{rows.map((r) => r.name + (label === 'Overdue' && r.daysUntil < 0 ? ` (${Math.abs(r.daysUntil)}d)` : '')).join(' · ')}</div>
                </div>
              ) : null)}
            </div>
          </div>
        )}

        {/* attachments */}
        {m.scope === 'full' && (m.attachments.visits.length > 0 || m.attachments.reports.length > 0) && (
          <div className="rep-sec">
            <div className="rep-sec-h"><span className="num">{N()}</span>Attached lab reports</div>
            <table className="rep-table">
              <thead><tr><th>Date</th><th>Source</th><th>Results</th></tr></thead>
              <tbody>
                {m.attachments.visits.slice(0, 10).map((v, i) => (
                  <tr key={i}><td>{TC.fmtDate(v.date)}</td><td>{v.type}{v.provider ? ` · ${v.provider}` : ''}</td><td className="val">{v.count}{v.scanned ? ` (${v.scanned} OCR)` : ''}</td></tr>
                ))}
              </tbody>
            </table>
            <div className="dmeta muted" style={{ marginTop: 8, lineHeight: 1.5 }}>Original reports remain on the patient's device. Values shown above were entered manually or read on-device via OCR and confirmed.</div>
          </div>
        )}

        <div className="card-flat row" style={{ padding: '11px 14px', gap: 10, marginTop: 4, marginBottom: 8 }}>
          <Icon name="info" size={15} color="var(--ink-3)" style={{ flex: 'none' }} />
          <span className="body" style={{ fontSize: 11.5, lineHeight: 1.5 }}>Self-reported summary generated by MUIY from the patient's records. Reference ranges are general; interpret against your laboratory's ranges and the clinical picture.</span>
        </div>

        <button className="btn btn-primary" style={{ width: '100%', gap: 8 }} onClick={doPrint}><Icon name="download" size={17} color="#fff" /> Save or print as PDF</button>
      </div>

      {/* print-only A4 document, portalled to <body> so the stylesheet can show
          it cleanly outside the scaled phone frame */}
      {ReactDOM.createPortal(<ReportPrintDoc model={m} ferBand={ferBand} hbBand={hbBand} />, document.body)}
    </div>
  );
}

/* ============================================================
   A4 PRINT DOCUMENT — clinical letterhead, page-broken.
   ============================================================ */
function ReportPrintDoc({ model, ferBand, hbBand }) {
  const m = model;
  const showMon = m.scope === 'full' || m.scope === 'monitoring';
  const showTx = m.scope === 'full' || m.scope === 'transfusion';
  const Foot = ({ n }) => (
    <div className="rp-foot"><span>{m.patient.name} · {m.patient.dob ? TC.fmtDate(m.patient.dob) : ''} · {m.patient.thalShort}</span><span>MUIY clinical summary · {TC.fmtDate(m.generatedAt)} · p.{n}</span></div>
  );
  const Lh = () => (
    <div className="rp-lh">
      <div className="brand">MUIY<small>Thalassaemia care companion</small></div>
      <div className="doc">Clinical Summary<br />{repFmtRange(m)}<br />Generated {TC.fmtDate(m.generatedAt)}</div>
    </div>
  );

  return (
    <div id="tc-print-root">
      {/* ---- PAGE 1 — cover + medical + transfusion ---- */}
      <div className="rp-page">
        <Lh />
        <div className="rp-h1">Medical Summary</div>
        <div style={{ fontSize: '9.5pt', color: '#5f7d7e', marginBottom: '12pt' }}>Patient-maintained clinical record · for review by the haematology / care team</div>

        <div className="rp-cover">
          <div className="f"><div className="k">Patient name</div><div className="v">{m.patient.name}</div></div>
          <div className="f"><div className="k">Date of birth</div><div className="v">{m.patient.dob ? TC.fmtDate(m.patient.dob) : '—'}{m.patient.age != null ? ` (${m.patient.age}y)` : ''}</div></div>
          <div className="f"><div className="k">Sex</div><div className="v">{m.patient.sex}</div></div>
          <div className="f"><div className="k">Blood group</div><div className="v">{m.patient.bloodGroup}</div></div>
          <div className="f"><div className="k">Diagnosis</div><div className="v">{m.patient.thalType}</div></div>
          <div className="f"><div className="k">Transfusion status</div><div className="v">{m.patient.thalShort}</div></div>
        </div>

        {m.scope === 'full' && (
          <React.Fragment>
            <div className="rp-h2"><span className="n">1</span>Clinical overview</div>
            <div className="rp-grid2">
              <div className="rp-box">
                <div className="bt">Current chelation</div>
                {m.medical.chelation.length ? m.medical.chelation.map((c, i) => (
                  <div key={i} className="rp-kv"><span className="k">{c.name}{c.brand && c.brand !== c.name ? ` (${c.brand})` : ''}</span><span className="v">{c.dose} · {c.freq}</span></div>
                )) : <div className="rp-kv"><span className="k">None on record</span><span className="v">—</span></div>}
              </div>
              <div className="rp-box">
                <div className="bt">Key details</div>
                <div className="rp-kv"><span className="k">Splenectomy</span><span className="v">{m.medical.splenectomy ? 'Yes' : 'No'}</span></div>
                <div className="rp-kv"><span className="k">Transfusion interval</span><span className="v">{m.medical.transfusionInterval || (m.transfusion.cadence ? `~${m.transfusion.cadence.weeks} wks` : '—')}</span></div>
                <div className="rp-kv"><span className="k">Weight</span><span className="v">{m.patient.weightKg ? `${m.patient.weightKg} kg` : '—'}</span></div>
                <div className="rp-kv"><span className="k">Treatment centre</span><span className="v">{m.patient.center || '—'}</span></div>
              </div>
            </div>
          </React.Fragment>
        )}

        {showTx && (
          <React.Fragment>
            <div className="rp-h2"><span className="n">{m.scope === 'full' ? '2' : '1'}</span>Transfusion summary</div>
            <div className="rp-grid2" style={{ marginBottom: '8pt' }}>
              <div className="rp-box">
                <div className="rp-kv"><span className="k">Sessions in period</span><span className="v">{m.transfusion.count}</span></div>
                <div className="rp-kv"><span className="k">Average interval</span><span className="v">{m.transfusion.cadence ? `${m.transfusion.cadence.weeks} weeks (${m.transfusion.cadence.avgDays}d)` : '—'}</span></div>
                <div className="rp-kv"><span className="k">Regularity</span><span className="v">{m.transfusion.cadence ? m.transfusion.cadence.regular : '—'}</span></div>
              </div>
              <div className="rp-box">
                <div className="rp-kv"><span className="k">Last transfusion</span><span className="v">{m.transfusion.last ? TC.fmtDate(m.transfusion.last.date) : '—'}</span></div>
                <div className="rp-kv"><span className="k">Next forecast</span><span className="v">{m.transfusion.forecast ? TC.fmtDate(m.transfusion.forecast.date) : '—'}</span></div>
                <div className="rp-kv"><span className="k">Pre-transfusion Hb</span><span className="v">{m.transfusion.hbStatus ? m.transfusion.hbStatus.label : '—'}</span></div>
              </div>
            </div>
            {m.transfusion.recent.length > 0 && (
              <table className="rp-ptable">
                <thead><tr><th>Date</th><th className="r">Units</th><th className="r">Volume</th><th>Reaction</th></tr></thead>
                <tbody>{m.transfusion.recent.map((t, i) => (
                  <tr key={i}><td>{TC.fmtDate(t.date)}</td><td className="r val">{t.units || '—'}</td><td className="r">{t.volumeMl ? `${t.volumeMl} mL` : '—'}</td><td>{t.reaction ? (t.reactionTypes || []).join(', ') || 'Yes' : 'None'}</td></tr>
                ))}</tbody>
              </table>
            )}
            {showTx && m.trends.haemoglobin.length >= 2 && (
              <div style={{ marginTop: '10pt' }}>
                <div className="bt" style={{ fontSize: '8.5pt', fontWeight: 800, letterSpacing: '.04em', textTransform: 'uppercase', color: '#7d9596', marginBottom: '4pt' }}>Pre-transfusion haemoglobin trend (g/dL)</div>
                <RepChart data={m.trends.haemoglobin} color="#C0392B" band={hbBand} print />
              </div>
            )}
          </React.Fragment>
        )}
        <Foot n={1} />
      </div>

      {/* ---- PAGE 2 — monitoring table + outstanding ---- */}
      {showMon && (
        <div className="rp-page">
          <Lh />
          <div className="rp-h2"><span className="n">{m.scope === 'full' ? '3' : '1'}</span>Monitoring summary</div>
          <table className="rp-ptable">
            <thead><tr><th>Test</th><th className="r">Latest result</th><th>Date</th><th>Reference</th><th>Status</th></tr></thead>
            <tbody>
              {m.monitoring.map((p) => (
                <React.Fragment key={p.key}>
                  <tr className="grp"><td colSpan={5}>{p.label}</td></tr>
                  {p.rows.map((r) => (
                    <tr key={r.id}>
                      <td>{r.name}</td>
                      <td className="r val" style={{ color: r.abnormal ? r.flag.color : '#16302f' }}>{r.abnormal && <span className="rp-flagdot" style={{ background: r.flag.color }} />}{r.value != null ? `${r.value}${r.unit ? ' ' + r.unit : ''}` : '—'}</td>
                      <td style={{ color: '#5f7d7e' }}>{r.date ? TC.fmtDate(r.date, { day: 'numeric', month: 'short', year: '2-digit' }) : '—'}</td>
                      <td style={{ color: '#5f7d7e', fontSize: '8pt' }}>{r.range ? `${r.range.low != null ? r.range.low : '—'}–${r.range.high != null ? r.range.high : '—'}` : '—'}</td>
                      <td><span className="rp-tag" style={{ background: r.statusMeta.wash, color: r.statusMeta.color }}>{r.statusMeta.label}</span></td>
                    </tr>
                  ))}
                </React.Fragment>
              ))}
            </tbody>
          </table>

          {(m.outstanding.overdue.length + m.outstanding.dueSoon.length + m.outstanding.missing.length > 0) && (
            <React.Fragment>
              <div className="rp-h2"><span className="n">{m.scope === 'full' ? '4' : '2'}</span>Outstanding monitoring</div>
              <div className="rp-grid2">
                {[['Overdue', m.outstanding.overdue, '#E5484D', '#FCEDEC'], ['Due soon', m.outstanding.dueSoon, '#D98300', '#FBEFD6'], ['Not yet recorded', m.outstanding.missing, '#5C7A80', '#EEF3F3']].map(([label, rows, color, wash]) => rows.length ? (
                  <div key={label} className="rp-box" style={{ borderColor: color, borderWidth: '1pt' }}>
                    <div className="bt" style={{ color }}>{label} ({rows.length})</div>
                    <div className="rp-list">{rows.map((r, i) => (
                      <div key={i} className="it"><span>{r.name}</span><span style={{ color: '#5f7d7e', fontWeight: 700 }}>{label === 'Overdue' ? `${Math.abs(r.daysUntil)}d over` : label === 'Due soon' ? `${r.daysUntil}d` : r.freqLabel}</span></div>
                    ))}</div>
                  </div>
                ) : null)}
              </div>
            </React.Fragment>
          )}
          <Foot n={2} />
        </div>
      )}

      {/* ---- PAGE 3 — trends + attachments ---- */}
      {showMon && (m.trends.ferritin.length >= 2 || m.attachments.visits.length > 0) && (
        <div className="rp-page">
          <Lh />
          {m.trends.ferritin.length >= 2 && (
            <React.Fragment>
              <div className="rp-h2"><span className="n">{m.scope === 'full' ? '5' : '3'}</span>Trend analysis — serum ferritin (ng/mL)</div>
              <RepChart data={m.trends.ferritin} color="#D9580B" band={ferBand} print />
              <div className="rp-note">Iron-load trend over the reporting period. The shaded band indicates the general target range; sustained values above it may warrant review of chelation.</div>
            </React.Fragment>
          )}
          {m.trends.creatinine.length >= 2 && (
            <React.Fragment>
              <div className="rp-h2"><span className="n">+</span>Trend analysis — creatinine (mg/dL)</div>
              <RepChart data={m.trends.creatinine} color="#1C96A0" band={MON.testById('creatinine') ? MON.testById('creatinine').normal_range : null} print />
            </React.Fragment>
          )}
          {m.scope === 'full' && (m.attachments.visits.length > 0) && (
            <React.Fragment>
              <div className="rp-h2"><span className="n">+</span>Attached lab reports &amp; sessions</div>
              <table className="rp-ptable">
                <thead><tr><th>Date</th><th>Source</th><th className="r">Results</th><th className="r">OCR</th></tr></thead>
                <tbody>{m.attachments.visits.slice(0, 14).map((v, i) => (
                  <tr key={i}><td>{TC.fmtDate(v.date)}</td><td>{v.type}{v.provider ? ` · ${v.provider}` : ''}</td><td className="r val">{v.count}</td><td className="r">{v.scanned || '—'}</td></tr>
                ))}</tbody>
              </table>
              <div className="rp-note">Original report files remain on the patient's device. Listed values were entered manually or extracted on-device via OCR and confirmed by the patient.</div>
            </React.Fragment>
          )}
          <Foot n={3} />
        </div>
      )}
    </div>
  );
}

Object.assign(window, { RepChart, MonReportConfigSheet, MonReportOverlay, ReportPrintDoc });
