/* ============================================================
   MUIY — Monitoring · Visits (date-centric)
   Browse results by lab session / visit. Every result belongs
   to a visit so a report's tests stay grouped for review.
   ============================================================ */

function MonVisitCard({ store, visit, onOpen }) {
  const stats = MON.visitStats(visit, store.data.testLogs || []);
  const m = MON.visitTypeMeta(visit.type);
  const d = TC.parse(visit.date);
  return (
    <button className="card" onClick={onOpen}
      style={{ display: 'block', width: '100%', textAlign: 'left', cursor: 'pointer', border: 'none', fontFamily: 'inherit', padding: 14, marginBottom: 10 }}>
      <div className="row" style={{ gap: 13, alignItems: 'center' }}>
        <div style={{ width: 44, flex: 'none', textAlign: 'center' }}>
          <div className="num" style={{ fontWeight: 800, fontSize: 21, lineHeight: 1, color: 'var(--ink)' }}>{d.getDate()}</div>
          <div className="dmeta muted" style={{ fontSize: 10.5, textTransform: 'uppercase', letterSpacing: '.04em', marginTop: 1 }}>{TC.fmtDate(visit.date, { month: 'short' })} {TC.fmtDate(visit.date, { year: '2-digit' })}</div>
        </div>
        <div style={{ width: 1, alignSelf: 'stretch', background: 'var(--hairline-2)' }} />
        <div style={{ flex: 1, minWidth: 0 }}>
          <span className="chip-status" style={{ background: m.wash, color: m.color, marginBottom: 6 }}><Icon name={m.icon} size={12} color={m.color} fill={m.icon === 'sparkle' || m.icon === 'drop' ? m.color : 'none'} />{m.label}</span>
          <div className="dname" style={{ fontSize: 14 }}>{stats.count} result{stats.count === 1 ? '' : 's'}{visit.provider ? ` · ${visit.provider}` : ''}</div>
          {stats.flags > 0
            ? <div className="dmeta" style={{ color: 'var(--danger)', fontWeight: 700, marginTop: 2 }}>{stats.flags} outside usual range</div>
            : <div className="dmeta muted" style={{ marginTop: 2 }}>All within usual range</div>}
        </div>
        <Icon name="chevR" size={16} color="var(--ink-3)" style={{ flex: 'none' }} />
      </div>
    </button>
  );
}

function MonVisitsView({ store, openVisit, openScan }) {
  const visits = MON.visitsOf(store.data);
  return (
    <div>
      {/* Upcoming appointments — the future-facing twin of the visits below.
          Set a date + reminder here; once the day passes it becomes the visit
          you attach results to. No separate tab. */}
      <UpcomingAppointments store={store} />

      {visits.length > 0 && (
        <React.Fragment>
          <div className="between" style={{ marginBottom: 9 }}>
            <span className="sec-title"><Icon name="calendar" size={14} color="var(--orange)" />Lab sessions &amp; visits</span>
            <span className="dmeta muted">{visits.length}</span>
          </div>
          {visits.map((v) => <MonVisitCard key={v.id} store={store} visit={v} onOpen={() => openVisit(v)} />)}
        </React.Fragment>
      )}
    </div>
  );
}

/* ---- Lab Reports tab: import a report → results grouped into a visit,
        plus a history of reports already imported via OCR/scan. ---- */
function LabReportsView({ store, openVisit, openScan }) {
  const logs = store.data.testLogs || [];
  const visits = MON.visitsOf(store.data);
  // a "report" = a visit that contains at least one scan-imported result
  const reports = visits.filter((v) => logs.some((l) => l.visitId === v.id && l.method === 'scan'));

  return (
    <div>
      <div className="card-flat row" style={{ padding: '12px 14px', gap: 11, marginBottom: 14 }}>
        <div className="leaf" style={{ width: 38, height: 38, flex: 'none', background: 'var(--orange-wash)', color: 'var(--orange)', borderRadius: 12 }}><Icon name="sparkle" size={18} color="var(--orange)" fill="var(--orange)" /></div>
        <span className="body" style={{ fontSize: 12.3, lineHeight: 1.45 }}>Paste or upload a lab report and MUIY pulls out the values, matches them to your tests, and groups them into a visit by date.</span>
      </div>

      <button className="btn btn-primary" style={{ width: '100%', marginBottom: 18 }} onClick={openScan}>
        <Icon name="sparkle" size={17} color="#fff" fill="#fff" /> Add results from a report
      </button>

      {reports.length === 0 ? (
        <div className="card"><div className="body" style={{ padding: '10px 0' }}>No reports imported yet. Tap <b>Add results from a report</b> above to import your first one.</div></div>
      ) : (
        <React.Fragment>
          <div className="between" style={{ marginBottom: 9 }}>
            <span className="sec-title"><Icon name="clipboard" size={14} color="var(--orange)" />Imported reports</span>
            <span className="dmeta muted">{reports.length}</span>
          </div>
          {reports.map((v) => <MonVisitCard key={v.id} store={store} visit={v} onOpen={() => openVisit(v)} />)}
        </React.Fragment>
      )}

      <div className="dmeta muted" style={{ textAlign: 'center', padding: '8px 20px', lineHeight: 1.5 }}>
        Each imported report becomes a visit, so its tests stay grouped. Original report files stay on your device.
      </div>
    </div>
  );
}

function MonVisitSheet({ store, close, visit, openTest }) {
  const logs = store.data.testLogs || [];
  const live = (store.data.visits || []).find((v) => v.id === visit.id) || visit;
  const m = MON.visitTypeMeta(live.type);
  const stats = MON.visitStats(live, logs);
  const setType = (t) => store.mutate((d) => { const v = (d.visits || []).find((x) => x.id === live.id); if (v) v.type = t; });

  return (
    <MSheet onClose={close}>
      <div className="row" style={{ gap: 12, marginBottom: 6 }}>
        <div className="leaf" style={{ width: 44, height: 44, flex: 'none', background: m.wash, color: m.color, borderRadius: 14 }}><Icon name={m.icon} size={20} color={m.color} fill={m.icon === 'sparkle' || m.icon === 'drop' ? m.color : 'none'} /></div>
        <div style={{ flex: 1, minWidth: 0 }}>
          <div className="h2" style={{ fontSize: 17 }}>{TC.fmtDate(live.date)}</div>
          <div className="dmeta muted">{m.label}{live.provider ? ` · ${live.provider}` : ''}</div>
        </div>
        <span className="chip-status" style={{ background: stats.flags > 0 ? 'var(--orange-wash)' : 'var(--green-wash)', color: stats.flags > 0 ? 'var(--orange)' : 'var(--success)', flex: 'none' }}>{stats.count} result{stats.count === 1 ? '' : 's'}</span>
      </div>

      <div className="seg" style={{ marginTop: 8, marginBottom: 14 }}>
        {['lab', 'imaging', 'clinic', 'review'].map((t) => (
          <button key={t} className={live.type === t ? 'on' : ''} style={{ fontSize: 11, padding: '8px 1px' }} onClick={() => setType(t)}>{MON.visitTypeMeta(t).label.split(' ')[0]}</button>
        ))}
      </div>

      <SLabel>Results in this session</SLabel>
      <div style={{ display: 'flex', flexDirection: 'column' }}>
        {stats.list.map((l) => {
          const test = MON.REGISTRY.find((x) => x.id === l.testId);
          if (!test) return null;
          const flag = test.normal_range ? MON.valueFlag(test, l.value) : null;
          const grp = MON.groupOfCat(test.category);
          return (
            <button key={l.id} className="drow" style={{ padding: '12px 0', cursor: 'pointer', border: 'none', background: 'none', fontFamily: 'inherit', width: '100%', textAlign: 'left', gap: 8 }} onClick={() => openTest(test)}>
              <div style={{ flex: 1, minWidth: 0 }}>
                <div className="dname" style={{ fontSize: 14 }}>{test.name}</div>
                <div className="dmeta muted">{grp ? grp.label : test.category}</div>
              </div>
              <div className="row" style={{ gap: 5, flex: 'none', alignItems: 'baseline' }}>
                <span className="num" style={{ fontSize: 15.5, fontWeight: 800, color: flag && flag.dir !== 'normal' ? flag.color : 'var(--ink)' }}>{l.value}</span>
                {l.unit && <span className="body" style={{ fontSize: 11 }}>{l.unit}</span>}
              </div>
              {flag && flag.dir !== 'normal' && <span style={{ width: 8, height: 8, borderRadius: 999, background: flag.color, flex: 'none', marginLeft: 4 }} />}
              <Icon name="chevR" size={15} color="var(--ink-3)" style={{ flex: 'none', marginLeft: 4 }} />
            </button>
          );
        })}
        {stats.list.length === 0 && <div className="body" style={{ padding: '12px 0' }}>No results in this session.</div>}
      </div>
      <div className="card-flat row" style={{ padding: '11px 14px', marginTop: 14, gap: 10 }}>
        <Icon name="info" size={15} color="var(--sky-deep)" style={{ flex: 'none' }} />
        <span className="body" style={{ fontSize: 12 }}>Tap any result to see its full history, trend and to edit or delete it.</span>
      </div>
    </MSheet>
  );
}

/* ============================================================
   AI REPORT EXTRACTION → groups results into a Visit.
   ============================================================ */
function monMatchTest(idOrName) {
  if (!idOrName) return null;
  const key = String(idOrName).toLowerCase().trim();
  let t = MON.REGISTRY.find((x) => x.id === key);
  if (t) return t;
  t = MON.REGISTRY.find((x) => x.name.toLowerCase() === key);
  if (t) return t;
  const toks = key.replace(/[^a-z0-9 ]/g, ' ').split(/\s+/).filter((w) => w.length > 2);
  let best = null, bestScore = 0;
  MON.REGISTRY.forEach((x) => {
    const hay = (x.id + ' ' + x.name).toLowerCase();
    let s = 0; toks.forEach((w) => { if (hay.includes(w)) s++; });
    if (s > bestScore) { bestScore = s; best = x; }
  });
  return bestScore >= 1 ? best : null;
}
function monParseJSON(txt) {
  if (!txt) return [];
  const s = txt.indexOf('['), e = txt.lastIndexOf(']');
  if (s === -1 || e === -1) return [];
  try { return JSON.parse(txt.slice(s, e + 1)); } catch (err) { return []; }
}

function MonScanSheet({ store, close, profile }) {
  const [stage, setStage] = React.useState('input'); // input | loading | confirm | error
  const [text, setText] = React.useState('');
  const [rows, setRows] = React.useState([]);
  const [err, setErr] = React.useState('');
  const fileRef = React.useRef(null);

  const onFile = (e) => {
    const f = e.target.files && e.target.files[0];
    if (!f) return;
    if (f.type.startsWith('text') || /\.(txt|csv)$/i.test(f.name)) {
      const r = new FileReader(); r.onload = () => setText(String(r.result || '')); r.readAsText(f);
    } else {
      store.showToast('Image read isn’t available here — paste the text', '📋');
    }
  };

  const extract = () => {
    if (!text.trim()) return;
    setErr('');
    // Deterministic, on-device parse — NO AI. Reuses the shared lab-import
    // parser (name · value · unit · range · date) and the fuzzy/synonym
    // catalog matcher; a token fallback covers anything it misses.
    try {
      const parsed = (window.LABX && LABX.parseReportText) ? LABX.parseReportText(text) : { meta: {}, tests: [] };
      const metaDate = (parsed.meta && (parsed.meta.collected || parsed.meta.reportDate)) || TC.daysAgoDate(0);
      const mapped = (parsed.tests || []).map((p) => {
        const fuzzy = (window.LABX && LABX.matchTest) ? LABX.matchTest(p.n) : null;
        const t = (fuzzy && fuzzy.score >= 0.5) ? MON.testById(fuzzy.testId) : monMatchTest(p.n);
        if (!t) return null;
        return { _id: TC.uid(), testId: t.id, name: t.name, unit: p.u || t.unit || null, value: p.v != null ? String(p.v) : '', date: metaDate, keep: true };
      }).filter(Boolean);
      const seen = {}; const uniq = [];
      mapped.forEach((m) => { if (!seen[m.testId]) { seen[m.testId] = 1; uniq.push(m); } });
      if (!uniq.length) { setErr('No matching results found. Paste a bit more of the report (with the test names and values), or enter results manually.'); setStage('error'); return; }
      setRows(uniq); setStage('confirm');
    } catch (e) {
      setErr('Couldn’t read that text. Please check the format, or enter results manually.'); setStage('error');
    }
  };

  const setRow = (id, k, v) => setRows((rs) => rs.map((r) => r._id === id ? { ...r, [k]: v } : r));
  const delRow = (id) => setRows((rs) => rs.filter((r) => r._id !== id));
  const [addOpen, setAddOpen] = React.useState(false);
  const [addQuery, setAddQuery] = React.useState('');
  const addable = MON.applicableTests(profile).filter((t) => !rows.some((r) => r.testId === t.id) && (t.name.toLowerCase().includes(addQuery.toLowerCase()) || t.id.includes(addQuery.toLowerCase())));
  const addTest = (t) => { setRows((rs) => [...rs, { _id: TC.uid(), testId: t.id, name: t.name, unit: t.unit || null, value: '', date: rows[0] ? rows[0].date : TC.daysAgoDate(0), keep: true }]); setAddOpen(false); setAddQuery(''); };

  const saveAll = () => {
    const good = rows.filter((r) => r.value.trim());
    if (!good.length) { close(); return; }
    store.mutate((d) => {
      d.testLogs = d.testLogs || [];
      good.forEach((r) => {
        const vid = MON.ensureVisit(d, r.date, r.testId);
        d.testLogs.push({ id: TC.uid(), testId: r.testId, date: r.date, value: r.value.trim(), unit: r.unit || null, method: 'scan', visitId: vid, notes: null, createdAt: new Date().toISOString() });
      });
    });
    const dates = Array.from(new Set(good.map((r) => r.date)));
    store.showToast(`${good.length} result${good.length === 1 ? '' : 's'} saved to ${dates.length === 1 ? 'a visit' : dates.length + ' visits'}`, '✅'); close();
  };

  return (
    <MSheet title={stage === 'confirm' ? 'I found these results' : 'Add results from a report'} onClose={close}>
      {stage === 'input' && (
        <div>
          <div className="card-flat row" style={{ padding: '11px 14px', gap: 10, marginBottom: 12 }}>
            <Icon name="sparkle" size={16} color="var(--orange)" />
            <span className="body" style={{ fontSize: 12.3, lineHeight: 1.45 }}>Paste the text from your lab report. The reader pulls out values, units and dates, matches them to your tests, and groups them into one visit.</span>
          </div>
          <textarea className="input textarea" rows={7} value={text} onChange={(e) => setText(e.target.value)} placeholder={'e.g.\nSerum Ferritin   1180 ng/mL\nTSH   5.2 mIU/L\nVitamin D   42 nmol/L\nCollected: 2026-05-12'} style={{ fontFamily: 'inherit', lineHeight: 1.5 }} />
          <div className="between" style={{ marginTop: 10, gap: 10 }}>
            <button className="link" style={{ padding: 0, fontSize: 12.5 }} onClick={() => fileRef.current && fileRef.current.click()}><Icon name="upload" size={14} color="var(--orange)" /> Upload .txt / .csv</button>
            <input ref={fileRef} type="file" accept=".txt,.csv,image/*,application/pdf" style={{ display: 'none' }} onChange={onFile} />
          </div>
          <button className="btn btn-primary" style={{ width: '100%', marginTop: 14 }} disabled={!text.trim()} onClick={extract}><Icon name="sparkle" size={17} color="#fff" /> Extract results</button>
        </div>
      )}

      {stage === 'loading' && (
        <div style={{ textAlign: 'center', padding: '38px 0' }}>
          <div className="leaf mon-pulse" style={{ width: 56, height: 56, margin: '0 auto 16px', background: 'var(--orange-wash)', color: 'var(--orange)', borderRadius: 18 }}><Icon name="sparkle" size={26} color="var(--orange)" fill="var(--orange)" /></div>
          <div className="h2" style={{ fontSize: 16 }}>Reading your report…</div>
          <div className="body" style={{ fontSize: 12.5, marginTop: 4 }}>Matching values to your monitoring tests</div>
        </div>
      )}

      {stage === 'error' && (
        <div>
          <MWarn>{err}</MWarn>
          <div className="row" style={{ gap: 10 }}>
            <button className="btn btn-ghost" style={{ flex: 1 }} onClick={() => setStage('input')}>Back</button>
            <button className="btn btn-primary" style={{ flex: 1 }} onClick={extract}>Try again</button>
          </div>
        </div>
      )}

      {stage === 'confirm' && (
        <div>
          <div className="card-flat row" style={{ padding: '10px 13px', gap: 9, marginBottom: 12 }}>
            <Icon name="info" size={15} color="var(--sky-deep)" style={{ flex: 'none' }} />
            <span className="body" style={{ fontSize: 12 }}>Check each value before saving — nothing is saved automatically. They’ll be grouped into a visit by date.</span>
          </div>
          <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
            {rows.map((r) => {
              const t = MON.REGISTRY.find((x) => x.id === r.testId);
              const flag = t && t.normal_range ? MON.valueFlag(t, r.value, profile) : null;
              return (
                <div key={r._id} className="card-flat" style={{ padding: 12 }}>
                  <div className="between" style={{ marginBottom: 9, gap: 8 }}>
                    <span className="dname" style={{ fontSize: 13.5 }}>{r.name}</span>
                    <button className="icon-btn" style={{ width: 30, height: 30, background: 'var(--surface-2)', flex: 'none' }} onClick={() => delRow(r._id)} aria-label="Remove"><Icon name="trash" size={14} color="var(--waiting)" /></button>
                  </div>
                  <div className="row" style={{ gap: 8 }}>
                    <div style={{ flex: 1.2 }}><input className="input" value={r.value} onChange={(e) => setRow(r._id, 'value', e.target.value)} placeholder="Value" style={{ borderColor: flag && flag.dir !== 'normal' ? flag.color : undefined }} /></div>
                    <div style={{ flex: 1 }}><input className="input" value={r.unit || ''} onChange={(e) => setRow(r._id, 'unit', e.target.value)} placeholder="Unit" /></div>
                  </div>
                  <div className="row" style={{ gap: 8, marginTop: 8, alignItems: 'center' }}>
                    <input className="input" type="date" value={r.date} onChange={(e) => setRow(r._id, 'date', e.target.value)} style={{ flex: 1 }} />
                    {flag && flag.dir !== 'normal' && <span className="chip-status" style={{ background: flag.wash, color: flag.color, flex: 'none' }}>{flag.label}</span>}
                  </div>
                </div>
              );
            })}
          </div>

          {addOpen ? (
            <div className="card-flat" style={{ padding: 12, marginTop: 10 }}>
              <input className="input" value={addQuery} onChange={(e) => setAddQuery(e.target.value)} placeholder="Search tests to add…" autoFocus />
              <div style={{ maxHeight: 168, overflowY: 'auto', marginTop: 8, scrollbarWidth: 'none' }}>
                {addable.slice(0, 12).map((t) => (
                  <button key={t.id} className="prow" style={{ border: 'none', background: 'none', cursor: 'pointer', fontFamily: 'inherit', width: '100%', textAlign: 'left', padding: '9px 4px' }} onClick={() => addTest(t)}>
                    <div style={{ flex: 1, minWidth: 0 }}><div className="dname" style={{ fontSize: 13.5 }}>{t.name}</div><div className="dmeta muted">{MON.groupOfCat(t.category) ? MON.groupOfCat(t.category).label : t.category}</div></div>
                    <Icon name="plus" size={16} color="var(--orange)" sw={2.4} />
                  </button>
                ))}
                {!addable.length && <div className="body" style={{ padding: '10px 4px', fontSize: 12.5 }}>No more tests to add.</div>}
              </div>
            </div>
          ) : (
            <button className="btn btn-ghost" style={{ width: '100%', marginTop: 10 }} onClick={() => setAddOpen(true)}><Icon name="plus" size={16} color="var(--ink)" /> Add a missing result</button>
          )}

          <div className="row" style={{ gap: 10, marginTop: 16 }}>
            <button className="btn btn-ghost" style={{ flex: 1 }} onClick={() => setStage('input')}>Back</button>
            <button className="btn btn-primary" style={{ flex: 1.5 }} onClick={saveAll}><Icon name="check" size={17} color="#fff" sw={2.6} /> Save {rows.filter((r) => r.value.trim()).length} result{rows.filter((r) => r.value.trim()).length === 1 ? '' : 's'}</button>
          </div>
        </div>
      )}
    </MSheet>
  );
}

/* ============================================================
   APPOINTMENTS — the future-facing twin of visits. ApptCard +
   the "Upcoming" strip shown atop this Visits view. Reads
   window.TC.appts; the add/edit sheet lives in sheets.jsx.
   ============================================================ */
function ApptCard({ store, appt, past }) {
  const A = TC.appts;
  const m = A.typeMeta(appt.type);
  const d = TC.parse(appt.date);
  const dU = A.daysUntil(appt);
  const soon = !past && dU >= 0 && dU <= 3;
  const rep = A.repeatMeta(appt.repeat);
  return (
    <button className="card" onClick={() => store.openModal('appointment', { edit: appt })}
      style={{ display: 'block', width: '100%', textAlign: 'left', cursor: 'pointer', border: 'none', fontFamily: 'inherit', padding: 14, marginBottom: 10, opacity: past ? 0.66 : 1 }}>
      <div className="row" style={{ gap: 13, alignItems: 'center' }}>
        <div style={{ width: 44, flex: 'none', textAlign: 'center' }}>
          <div className="num" style={{ fontWeight: 800, fontSize: 21, lineHeight: 1, color: soon ? m.color : 'var(--ink)' }}>{d.getDate()}</div>
          <div className="dmeta muted" style={{ fontSize: 10.5, textTransform: 'uppercase', letterSpacing: '.04em', marginTop: 1 }}>{TC.fmtDate(appt.date, { month: 'short' })} {TC.fmtDate(appt.date, { year: '2-digit' })}</div>
        </div>
        <div style={{ width: 1, alignSelf: 'stretch', background: 'var(--hairline-2)' }} />
        <div style={{ flex: 1, minWidth: 0 }}>
          <div className="row" style={{ gap: 6, marginBottom: 5, flexWrap: 'wrap' }}>
            <span className="chip-status" style={{ background: m.wash, color: m.color }}><Icon name={m.icon} size={12} color={m.color} fill={m.icon === 'sparkle' || m.icon === 'drop' || m.icon === 'heart' ? m.color : 'none'} />{m.short}</span>
            {!past && <span className="chip-status" style={{ background: soon ? 'var(--orange-wash)' : 'var(--surface-2)', color: soon ? 'var(--orange)' : 'var(--ink-2)' }}>{A.whenLabel(appt)}</span>}
          </div>
          <div className="dname" style={{ fontSize: 14.5, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{appt.title}</div>
          <div className="dmeta muted" style={{ marginTop: 2, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>
            {appt.time ? A.fmtTime(appt.time) : 'Time not set'}{appt.location ? ` · ${appt.location}` : ''}{rep.months ? ` · ${rep.label.toLowerCase()}` : ''}
          </div>
        </div>
        <Icon name="chevR" size={16} color="var(--ink-3)" style={{ flex: 'none' }} />
      </div>
    </button>
  );
}

function UpcomingAppointments({ store }) {
  const A = TC.appts;
  if (!A) return null;
  const up = A.upcoming(store.data);
  const pastA = A.past(store.data).slice(0, 4);
  const [showPast, setShowPast] = React.useState(false);
  return (
    <div style={{ marginBottom: 18 }}>
      <div className="between" style={{ marginBottom: 9 }}>
        <span className="sec-title"><Icon name="calendar" size={14} color="var(--orange)" />Upcoming appointments</span>
        <button className="link" style={{ fontSize: 12.5, fontWeight: 800 }} onClick={() => store.openModal('appointment', {})}><Icon name="plus" size={13} color="var(--orange)" sw={2.6} /> Add</button>
      </div>

      {up.length === 0 ? (
        <button className="card-flat" onClick={() => store.openModal('appointment', {})}
          style={{ width: '100%', textAlign: 'left', border: '1.5px dashed var(--hairline-2)', background: 'transparent', cursor: 'pointer', fontFamily: 'inherit', padding: '14px 15px', display: 'flex', gap: 12, alignItems: 'center' }}>
          <span className="leaf" style={{ width: 40, height: 40, flex: 'none', background: 'var(--orange-wash)', color: 'var(--orange)', borderRadius: 13 }}><Icon name="calendar" size={19} color="var(--orange)" /></span>
          <span style={{ flex: 1, minWidth: 0 }}>
            <span style={{ display: 'block', fontWeight: 800, fontSize: 14, color: 'var(--ink)' }}>Add your next appointment</span>
            <span className="body" style={{ display: 'block', fontSize: 12, marginTop: 1 }}>Set a date and we’ll remind you ahead of time.</span>
          </span>
          <Icon name="chevR" size={16} color="var(--ink-3)" style={{ flex: 'none' }} />
        </button>
      ) : (
        up.map((a) => <ApptCard key={a.id} store={store} appt={a} />)
      )}

      {pastA.length > 0 && (
        <div style={{ marginTop: 6 }}>
          <button className="link" style={{ fontSize: 12.5, padding: '4px 0' }} onClick={() => setShowPast((v) => !v)}>
            <Icon name="chevD" size={13} color="var(--orange)" style={{ transform: showPast ? 'rotate(180deg)' : 'none', transition: 'transform .2s' }} /> {showPast ? 'Hide' : 'Show'} past appointments
          </button>
          {showPast && <div style={{ marginTop: 8 }}>{pastA.map((a) => <ApptCard key={a.id} store={store} appt={a} past />)}</div>}
        </div>
      )}
    </div>
  );
}

Object.assign(window, { MonVisitCard, MonVisitsView, LabReportsView, MonVisitSheet, MonScanSheet, ApptCard, UpcomingAppointments });
