/* MedBridge clinician workspace — neumorphic redesign (ds.css / .mbx),
   wired to the real window.PT FHIR data. Replaces the old patient_app/
   patient_views/patient_summary trio. Defines window.PatientApp. */

const { useState: uS, useEffect: uE, useRef: uR } = React;

/* ---------- inline icon sprite (Lucide-style) ---------- */
const MBX_SPRITE = `
<symbol id="i-spark" viewBox="0 0 24 24"><path d="M12 3l1.9 5.6a3 3 0 0 0 1.9 1.9L21.5 12l-5.7 1.5a3 3 0 0 0-1.9 1.9L12 21l-1.9-5.6a3 3 0 0 0-1.9-1.9L2.5 12l5.7-1.5a3 3 0 0 0 1.9-1.9z"/></symbol>
<symbol id="i-clock" viewBox="0 0 24 24"><circle cx="12" cy="12" r="9"/><path d="M12 7.5V12l3.5 2"/></symbol>
<symbol id="i-pill" viewBox="0 0 24 24"><path d="M10.5 20.5 20.5 10.5a4.95 4.95 0 1 0-7-7L3.5 13.5a4.95 4.95 0 1 0 7 7Z"/><path d="m8.5 8.5 7 7"/></symbol>
<symbol id="i-image" viewBox="0 0 24 24"><rect x="3" y="3" width="18" height="18" rx="2.5"/><circle cx="8.5" cy="8.5" r="1.6"/><path d="m21 15-4.5-4.5L7 20"/></symbol>
<symbol id="i-flask" viewBox="0 0 24 24"><path d="M9 3h6"/><path d="M10 3v6L4.7 18.6A1.4 1.4 0 0 0 5.9 21h12.2a1.4 1.4 0 0 0 1.2-2.4L14 9V3"/><path d="M7.2 15.5h9.6"/></symbol>
<symbol id="i-alert" viewBox="0 0 24 24"><path d="M12 3.2 2.6 19.5A1.1 1.1 0 0 0 3.6 21.2h16.8a1.1 1.1 0 0 0 1-1.7z"/><path d="M12 9v5"/><path d="M12 17.4h.01"/></symbol>
<symbol id="i-shield" viewBox="0 0 24 24"><path d="M12 3 5 6v5.5c0 4.4 3 7.6 7 9 4-1.4 7-4.6 7-9V6z"/><path d="m9 12 2.2 2.2L15.5 10"/></symbol>
<symbol id="i-search" viewBox="0 0 24 24"><circle cx="11" cy="11" r="7"/><path d="m20.5 20.5-4-4"/></symbol>
<symbol id="i-hospital" viewBox="0 0 24 24"><path d="M3 21h18"/><path d="M5 21V5a1 1 0 0 1 1-1h12a1 1 0 0 1 1 1v16"/><path d="M12 7v5M9.5 9.5h5"/><path d="M9 21v-3.5h6V21"/></symbol>
<symbol id="i-chevd" viewBox="0 0 24 24"><path d="m6 9.5 6 6 6-6"/></symbol>
<symbol id="i-chevr" viewBox="0 0 24 24"><path d="m9.5 6 6 6-6 6"/></symbol>
<symbol id="i-send" viewBox="0 0 24 24"><path d="M22 2 11 13"/><path d="M22 2 15 22l-4-9-9-4z"/></symbol>
<symbol id="i-check" viewBox="0 0 24 24"><path d="m5 12.5 4.5 4.5L19.5 7"/></symbol>
<symbol id="i-sliders" viewBox="0 0 24 24"><path d="M4 21v-6M4 11V3M12 21v-9M12 8V3M20 21v-4M20 13V3"/><path d="M2 15h4M10 8h4M18 17h4"/></symbol>
<symbol id="i-logout" viewBox="0 0 24 24"><path d="M15 3h3.5a1.5 1.5 0 0 1 1.5 1.5v15a1.5 1.5 0 0 1-1.5 1.5H15"/><path d="m10 16 4-4-4-4"/><path d="M14 12H3"/></symbol>
<symbol id="i-signaloff" viewBox="0 0 24 24"><path d="m2 2 20 20"/><path d="M5 12.5a9 9 0 0 1 3.5-2.3"/><path d="M2.5 8.5A14 14 0 0 1 6 6.2"/><path d="M21.5 8.5a14 14 0 0 0-5.5-3.1"/><path d="M8.5 16a5 5 0 0 1 6.5-.5"/><path d="M12 20h.01"/></symbol>
<symbol id="i-database" viewBox="0 0 24 24"><ellipse cx="12" cy="5" rx="8" ry="3"/><path d="M4 5v6c0 1.7 3.6 3 8 3s8-1.3 8-3V5"/><path d="M4 11v6c0 1.7 3.6 3 8 3s8-1.3 8-3v-6"/></symbol>
<symbol id="i-note" viewBox="0 0 24 24"><path d="M14 3H7a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V8z"/><path d="M14 3v5h5"/><path d="M8.5 13h7M8.5 17h4"/></symbol>
<symbol id="i-droplet" viewBox="0 0 24 24"><path d="M12 3s6 5.7 6 10.5a6 6 0 0 1-12 0C6 8.7 12 3 12 3z"/></symbol>
<symbol id="i-pulse" viewBox="0 0 24 24"><path d="M3 12h4l2.5 7 5-14L17 12h4"/></symbol>
<symbol id="i-bed" viewBox="0 0 24 24"><path d="M3 8v11M3 13h18a0 0 0 0 1 0 0v6M21 19v-6a3 3 0 0 0-3-3H9"/><circle cx="7" cy="11" r="1.6"/></symbol>
<symbol id="i-x" viewBox="0 0 24 24"><path d="M6 6 18 18M18 6 6 18"/></symbol>`;

function Spr({ id, size, style }) {
  const cls = "ic" + (size ? " s" + size : "");
  return <svg className={cls} style={style}><use href={"#" + id} /></svg>;
}
const NAV_ICON = { summary: "i-spark", timeline: "i-clock", meds: "i-pill", imaging: "i-image", labs: "i-flask", allergies: "i-alert" };
const ACUITY_LABEL = { critical: "Critical", watch: "Watch", stable: "Stable" };
function initials(p) { return ((p.first[0] || "") + (p.last[0] || "")).toUpperCase(); }
function hueColor(h) { return `hsl(${h} 42% 46%)`; }
const SRC_ORDER = ["oracle", "epic", "meditech", "telus"];

/* ---------- safety computations (all from real data) ---------- */
function safetyTiles(p) {
  const al = p.allergies || [], meds = p.meds || [], labs = p.labs || [];
  // allergies
  const unconf = al.some((a) => a.status !== "confirmed");
  let alT;
  if (!al.length) alT = { cls: "crit", val: "None on file", chip: "No record", note: "No structured allergy record returned — confirm verbally before any antibiotic.", ic: "i-alert" };
  else if (unconf) alT = { cls: "crit", val: al.find((a) => a.status !== "confirmed").agent, chip: "Not reconciled", note: "Found unconfirmed — reconcile before antibiotic orders.", ic: "i-alert" };
  else alT = { cls: "ok", val: al.length + " on file", chip: "Reconciled", note: "Coded allergies present and confirmed.", ic: "i-shield" };
  // do-not-interrupt
  const crit = meds.filter((m) => m.critical);
  const diT = crit.length
    ? { cls: "warn", val: crit.slice(0, 2).map((m) => m.name.split(" (")[0]).join(" + "), chip: "Anticoagulated", note: "Anticoagulant / antiplatelet on list. Verify last dose before any procedure.", ic: "i-droplet" }
    : { cls: "ok", val: "None flagged", chip: "Clear", note: "No anticoagulant or antiplatelet on the active list.", ic: "i-droplet" };
  // critical labs
  const hh = labs.find((l) => l.flag === "HH"), h = labs.find((l) => l.flag === "H");
  let labT;
  if (hh) labT = { cls: "crit", val: `${hh.name} ${hh.val}`, chip: "Critical high", note: `Ref ${hh.ref} ${hh.unit} · ${hh.date}`, ic: "i-pulse" };
  else if (h) labT = { cls: "warn", val: `${h.name} ${h.val}`, chip: "High", note: `Ref ${h.ref} ${h.unit} · ${h.date}`, ic: "i-pulse" };
  else labT = { cls: "ok", val: labs.length ? "No flags" : "No labs", chip: labs.length ? "In range" : "None returned", note: labs.length ? "No out-of-range results in returned labs." : "Repeat a panel on arrival.", ic: "i-pulse" };
  // data picture
  const responded = (p.connected || []).length;
  const dpT = { cls: "gap", val: `${responded} of 4 systems`, chip: responded < 4 ? "Picture incomplete" : "Complete", note: dataNote(p), ic: "i-signaloff" };
  return [
    { key: "allergies", lab: "Allergies", ...alT, to: "allergies" },
    { key: "dni", lab: "Do-not-interrupt", ...diT, to: "meds" },
    { key: "labs", lab: "Critical labs", ...labT, to: "labs" },
    { key: "data", lab: "Data picture", ...dpT, to: null },
  ];
}
function dataNote(p) {
  const names = (p.connected || []).map((id) => window.PT.sources[id].name);
  return `${names.join(", ") || "No system"} returned records; other connected systems returned no match — picture may be incomplete.`;
}
function dataRows(p) {
  return SRC_ORDER.map((id) => {
    const s = window.PT.sources[id];
    const on = (p.connected || []).includes(id);
    const unreachable = /no endpoint|no api/i.test(s.span || "");
    return { s, on, unreachable };
  });
}

/* ---------- shared bits ---------- */
function SrcPill({ id }) {
  const s = window.PT.sources[id]; if (!s) return null;
  return <span className="src-pill" style={{ background: s.bg, color: s.color }}><i style={{ background: s.color }} />{s.name}</span>;
}
function SecH({ children }) { return <div className="sec-h"><h2>{children}</h2><span className="rule" /></div>; }
function Empty({ ic, t, n }) { return <div className="empty"><div className="eic"><Spr id={ic} size={26} /></div><div className="et">{t}</div><div className="en">{n}</div></div>; }

/* ---------- section views ---------- */
function TimelineFull({ p }) {
  const rows = p.timeline || [];
  if (!rows.length) return <Empty ic="i-clock" t="No timeline events transferred" n="No connected system returned dated encounters. Obtain collateral history from the sending site." />;
  return <>
    <p className="lead">Every dated encounter MedBridge could assemble across connected systems, most recent first.</p>
    <div className="tl">{rows.map((e, i) => <TlRow key={i} e={e} />)}</div>
  </>;
}
function TlRow({ e }) {
  const s = window.PT.sources[e.src];
  return <div className="tl-row">
    <span className="tl-date tnum">{e.date}</span>
    <div className="tl-main"><div className="ttl">{e.title}{e.flag === "critical" && <span className="tl-pill">Critical</span>}</div><div className="det">{e.detail}</div></div>
    {s && <span className="src"><i style={{ background: s.color }} />{s.name}</span>}
  </div>;
}
function MedsView({ p }) {
  const meds = p.meds || [];
  if (!meds.length) return <Empty ic="i-pill" t="No active medication list on record" n="No connected system returned a structured medication list. Confirm current medications verbally before ordering." />;
  return <>
    <p className="lead">{meds.length} active medication{meds.length !== 1 ? "s" : ""} pulled live. Anticoagulant / antiplatelet therapy is flagged — do not interrupt.</p>
    {meds.map((m, i) => <div className={"rec" + (m.critical ? " crit" : "")} key={i}>
      <div className="ric"><Spr id="i-pill" /></div>
      <div className="rmain">
        <div className="rname">{m.name}{m.critical && <span className="badge crit">Do not interrupt</span>}</div>
        <div className="rsub">{[m.dose, m.route, m.cls].filter(Boolean).join(" · ")}</div>
        <div className="rnote">{m.note}</div>
      </div>
      <div className="rright"><SrcPill id={m.src} /></div>
    </div>)}
  </>;
}
function LabsView({ p }) {
  const labs = p.labs || [];
  if (!labs.length) return <Empty ic="i-flask" t="No recent labs transferred" n="No connected system returned laboratory results. Repeat a full panel on arrival." />;
  return <>
    <p className="lead">Most recent result per test across all responding sources. Out-of-range values flagged.</p>
    {labs.map((l, i) => <div className={"rec" + (l.flag === "HH" ? " crit" : "")} key={i}>
      <div className="ric"><Spr id="i-flask" /></div>
      <div className="rmain">
        <div className="rname">{l.name}{l.flag && <span className={"flagpill " + l.flag}>{l.flag === "HH" ? "Critical high" : "High"}</span>}</div>
        <div className="rsub">Reference {l.ref} {l.unit}</div>
        <div style={{ marginTop: 6 }}><SrcPill id={l.src} /></div>
      </div>
      <div className="rright"><span className={"rval" + (l.flag ? " hi" : "")}>{l.val}<span style={{ fontSize: 12, fontWeight: 600, color: "var(--ink-3)", marginLeft: 3 }}>{l.unit}</span></span><span className="rdate">{l.date}</span></div>
    </div>)}
  </>;
}
function downloadReport(r) {
  const src = (window.PT.sources[r.src] || {}).name || "—";
  const text = [
    "MEDBRIDGE — IMAGING REPORT", "=".repeat(46),
    `Study   : ${r.title} (${r.mod})`, `Date    : ${r.date}`,
    `Facility: ${r.site}`, `Source  : ${src}`, "",
    "IMPRESSION / REPORT", "-".repeat(46), r.read, "",
    "Generated by MedBridge · AI-assisted summary of the source report.",
    "Verify against the originating system before clinical decisions.",
  ].join("\n");
  const a = document.createElement("a");
  a.href = URL.createObjectURL(new Blob([text], { type: "text/plain" }));
  a.download = `${r.title.replace(/[^a-z0-9]+/gi, "_")}_${r.date.replace(/\s+/g, "")}.txt`;
  document.body.appendChild(a); a.click(); a.remove(); URL.revokeObjectURL(a.href);
}
function ReportModal({ r, onClose }) {
  uE(() => { const h = (e) => e.key === "Escape" && onClose(); window.addEventListener("keydown", h); return () => window.removeEventListener("keydown", h); }, []);
  return <div className="lk-overlay" onClick={onClose}><div className="report-modal" onClick={(e) => e.stopPropagation()}>
    <div className="rm-head">
      <span className="rm-ic"><Spr id="i-note" size={20} /></span>
      <div style={{ flex: 1 }}><div className="rm-t">{r.title} <span className="badge neutral">{r.mod}</span></div><div className="rm-m">Report · {r.date} · {r.site}</div></div>
      <button className="rm-x" onClick={onClose}><Spr id="i-x" size={20} /></button>
    </div>
    <div className="rm-body">
      <div className="rm-label">Impression / report</div>
      <p className="rm-read">{r.read}</p>
      <div className="rm-meta"><SrcPill id={r.src} /><span className="rm-note"><Spr id="i-shield" size={14} />Read live from the source system · not copied or stored by MedBridge</span></div>
    </div>
    <div className="rm-foot"><button className="btn sm ghost" onClick={onClose}>Close</button><button className="btn primary" onClick={() => downloadReport(r)}><Spr id="i-send" size={14} />Download report</button></div>
  </div></div>;
}
function ImageViewer({ r, onClose }) {
  uE(() => { const h = (e) => e.key === "Escape" && onClose(); window.addEventListener("keydown", h); return () => window.removeEventListener("keydown", h); }, []);
  return <div className="lk-overlay" onClick={onClose}><div className="report-modal" onClick={(e) => e.stopPropagation()}>
    <div className="rm-head">
      <span className="rm-ic"><Spr id="i-image" size={20} /></span>
      <div style={{ flex: 1 }}><div className="rm-t">{r.title} <span className="badge neutral">{r.mod}</span></div><div className="rm-m">Image viewer · {r.date} · {r.site}</div></div>
      <button className="rm-x" onClick={onClose}><Spr id="i-x" size={20} /></button>
    </div>
    <div className="rm-body">
      <div className="iv-frame">
        <div className="iv-scan" />
        <div className="iv-hud tl">{r.mod} · {r.site}</div>
        <div className="iv-hud tr">{r.date}</div>
        <div className="iv-hud bl">SER 1 / IMG 1</div>
        <div className="iv-overlay"><Spr id="i-image" size={26} /><div>DICOM not exposed by this endpoint</div></div>
      </div>
      <div className="rm-meta"><SrcPill id={r.src} /><span className="rm-note"><Spr id="i-shield" size={14} />Pixel data stays in the facility PACS · MedBridge links out, never copies images</span></div>
      <p style={{ fontSize: 12.5, color: "var(--ink-3)", marginTop: 10, lineHeight: 1.5 }}>The full study opens in the originating facility's PACS / DICOM viewer via the FHIR <b>ImagingStudy.endpoint</b> (DICOMweb / WADO). Sandbox endpoints don't expose raw pixel data, so a representative frame is shown here.</p>
    </div>
    <div className="rm-foot"><button className="btn sm ghost" onClick={onClose}>Close</button><button className="btn primary"><Spr id="i-image" size={14} />Open in PACS viewer</button></div>
  </div></div>;
}
function ImagingView({ p }) {
  const im = p.imaging || [];
  const [rep, setRep] = uS(null);
  const [img, setImg] = uS(null);
  if (!im.length) return <Empty ic="i-image" t="No imaging or reports transferred" n="No diagnostic reports were returned by any connected system. Prior imaging may exist at the sending site." />;
  return <>
    <p className="lead">Imaging studies across connected sources. Open the <b>image</b> in the facility viewer, or read &amp; download the <b>report</b> — nothing is copied or stored centrally.</p>
    {im.map((r, i) => <div className="rec" key={i}>
      <div className="ric"><Spr id="i-image" /></div>
      <div className="rmain"><div className="rname">{r.title}<span className="badge neutral">{r.mod}</span></div><div className="rsub">{r.read}</div><div className="rnote">{r.site}</div></div>
      <div className="rright">
        <span className="rdate">{r.date}</span><SrcPill id={r.src} />
        <div className="img-actions">
          <button className="mini-btn" onClick={() => setImg(r)}><Spr id="i-image" size={14} />Image</button>
          <button className="mini-btn primary" onClick={() => setRep(r)}><Spr id="i-note" size={14} />Report</button>
        </div>
      </div>
    </div>)}
    {rep && <ReportModal r={rep} onClose={() => setRep(null)} />}
    {img && <ImageViewer r={img} onClose={() => setImg(null)} />}
  </>;
}
function AllergiesView({ p }) {
  const al = p.allergies || [];
  const [rec, setRec] = uS({});
  const anyUnconf = al.some((a) => a.status !== "confirmed");
  return <>
    {(!al.length || anyUnconf) && <div className="alertbar"><span className="abic"><Spr id="i-alert" size={20} /></span><div className="abtx">{al.length === 0
      ? <><b>No structured allergy record exists in any connected system.</b> Confirm allergies verbally before ordering any new medication, especially antibiotics.</>
      : <><b>An allergy is unconfirmed.</b> It must be formally reconciled before antibiotic orders.</>}</div></div>}
    {!al.length ? <Empty ic="i-shield" t="No allergies on the active list" n="This is an absence of data, not a confirmed absence of allergies. Reconcile manually." />
      : al.map((a, i) => <div className={"rec" + (a.status !== "confirmed" ? " crit" : "")} key={i}>
        <div className="ric"><Spr id={a.status === "confirmed" ? "i-shield" : "i-alert"} /></div>
        <div className="rmain">
          <div className="rname">{a.agent}{a.status === "confirmed" ? <span className="badge ok">Confirmed</span> : <span className="badge warn">Unconfirmed</span>}{!a.coded && <span className="badge neutral">Not coded</span>}</div>
          <div className="rsub">Reaction: {a.reaction} · Severity: {a.severity}</div>
          <div className="rnote">{a.note}</div>
          <div style={{ marginTop: 9, display: "flex", gap: 8, alignItems: "center", flexWrap: "wrap" }}>
            <SrcPill id={a.src} />
            {a.status === "confirmed" ? null : rec[i] ? <span className="badge ok"><Spr id="i-check" size={14} />Reconciled</span>
              : <button className="recon" onClick={() => setRec((o) => ({ ...o, [i]: true }))}><Spr id="i-check" size={14} />Reconcile to active list</button>}
          </div>
        </div>
      </div>)}
  </>;
}

/* ---------- AI summary ---------- */
function AISummary({ p, onAccept, onAsk }) {
  const S = p.summary || {};
  const baseProse = S.prose && S.prose.length ? S.prose : [{ t: S.headline || "" }];
  const [ans, setAns] = uS(null);
  const [body, setBody] = uS(baseProse);
  const [editing, setEditing] = uS(false);
  const [draft, setDraft] = uS("");
  const [edited, setEdited] = uS(false);
  const [flagged, setFlagged] = uS(false);
  function ask(q) { setAns({ q, a: (S.answers && S.answers[q]) || "Grounded in the connected records — try one of the suggested questions." }); if (onAsk) onAsk(q); }
  const effectiveText = body.map((x) => x.t).join(" ");
  function startEdit() { setDraft(body.map((x) => x.t).join("\n\n")); setEditing(true); }
  function saveEdit() {
    const paras = draft.split(/\n{2,}/).map((t) => t.trim()).filter(Boolean).map((t) => ({ t }));
    setBody(paras.length ? paras : [{ t: draft.trim() }]); setEdited(true); setEditing(false); setFlagged(false);
  }
  return <div className="ai">
    <div className="ai-h">
      <span className="sp"><Spr id="i-spark" size={16} style={{ stroke: "#fff" }} /></span>
      <div><div className="t">Patient summary{edited && <span className="badge neutral" style={{ marginLeft: 8 }}>edited</span>}</div><div className="m">MedBridge AI · grounded in {(p.connected || []).length} of 4 responding sources · most recent first</div></div>
      <span className="badge brand" style={{ marginLeft: "auto" }}>claude</span>
    </div>
    {editing
      ? <div className="ai-b"><textarea className="ai-edit" value={draft} onChange={(e) => setDraft(e.target.value)} autoFocus placeholder="Edit the summary… (a blank line separates paragraphs)" /></div>
      : <div className="ai-b">
          {body.map((x, i) => <p key={i} className={x.crit ? "flag" : ""}>{x.t}</p>)}
          {flagged && <p style={{ color: "var(--warn-d)", fontWeight: 600 }}>⚑ Flagged as incorrect — won't be accepted into the record until reviewed.</p>}
        </div>}
    {!editing && S.chips && S.chips.length > 0 && <div className="chips">{S.chips.map((c, i) => <button key={i} className="chip-q" onClick={() => ask(c)}>{c}<Spr id="i-send" size={14} /></button>)}</div>}
    {!editing && ans && <div className="ans"><b>{ans.q}</b><br />{ans.a}</div>}
    <div className="ai-foot">
      {editing ? <>
        <button className="btn primary" onClick={saveEdit}><Spr id="i-check" size={14} />Save edits</button>
        <button className="btn sm" onClick={() => setEditing(false)}>Cancel</button>
      </> : <>
        <button className="btn primary" disabled={flagged} style={flagged ? { opacity: .5, cursor: "not-allowed" } : null} onClick={() => !flagged && onAccept(effectiveText, edited)}><Spr id="i-check" size={14} />Accept into note</button>
        <button className="btn sm" onClick={startEdit}>Edit</button>
        <button className={"btn sm ghost" + (flagged ? " accepted" : "")} onClick={() => setFlagged((f) => !f)}>{flagged ? "Flagged" : "Flag incorrect"}</button>
      </>}
      <span className="disc"><Spr id="i-spark" size={14} />AI-assisted · verify before clinical decisions</span>
    </div>
  </div>;
}

/* ---------- modals ---------- */
function Lookup({ activeId, onPick, onClose }) {
  const { patients } = window.PT;
  const [q, setQ] = uS(""); const ref = uR(null);
  uE(() => { ref.current && ref.current.focus(); }, []);
  uE(() => { const h = (e) => e.key === "Escape" && onClose(); window.addEventListener("keydown", h); return () => window.removeEventListener("keydown", h); }, []);
  const s = q.trim().toLowerCase();
  const rows = patients
    .filter((p) => !s || `${p.first} ${p.last}`.toLowerCase().includes(s) || (p.hcn || "").toLowerCase().includes(s) || (p.dob || "").includes(s) || (p.origin || "").toLowerCase().includes(s) || (p.chief || "").toLowerCase().includes(s))
    .sort((a, b) => `${a.last} ${a.first}`.localeCompare(`${b.last} ${b.first}`));
  return <div className="lk-overlay" onClick={onClose}><div className="lk-modal" onClick={(e) => e.stopPropagation()}>
    <div className="lk-search"><Spr id="i-search" size={20} /><input ref={ref} value={q} onChange={(e) => setQ(e.target.value)} placeholder="Search by name, health card, date of birth, or source…" /><span className="esc">ESC</span></div>
    <div className="lk-scope">Inbound to {window.PT.clinic.facility} · {s ? `${rows.length} of ${patients.length}` : patients.length} patient{(s ? rows.length : patients.length) !== 1 ? "s" : ""} · A–Z</div>
    <div className="lk-list">{rows.length === 0 ? <div className="lk-empty">No patients match “{q}”.</div> : rows.map((p) => {
      const n = (p.connected || []).length;
      return <button key={p.id} className={"lk-row" + (p.id === activeId ? " sel" : "")} onClick={() => onPick(p.id)}>
        <span className="lk-av" style={{ background: hueColor(p.avatarHue) }}>{initials(p)}</span>
        <span className="lr-main">
          <span className="lr-name"><span className={"ad " + p.acuity} />{p.first} {p.last}, {p.age}{p.sex}</span>
          <span className="lr-id">{p.hcn} · DOB {p.dob} · {p.origin}</span>
          <span className="lr-chief">{p.chief}</span>
        </span>
        <span className="lr-right">
          <span className="lr-srcs">{(p.connected || []).map((id) => <SrcPill key={id} id={id} />)}</span>
          <span className={"lk-src-ct" + (n <= 1 ? " low" : "")}>{n}/4 sources</span>
        </span>
      </button>;
    })}</div>
    <div className="lk-foot"><Spr id="i-shield" size={14} />Federated lookup · identifiers shown to authorized clinical users only · all access audit-logged</div>
  </div></div>;
}
function FacilityPicker({ activeId, onPick, onClose }) {
  const { facilities } = window.PT;
  const [q, setQ] = uS(""); const ref = uR(null);
  uE(() => { ref.current && ref.current.focus(); }, []);
  uE(() => { const h = (e) => e.key === "Escape" && onClose(); window.addEventListener("keydown", h); return () => window.removeEventListener("keydown", h); }, []);
  const s = q.trim().toLowerCase();
  const rows = facilities.filter((f) => !s || f.facility.toLowerCase().includes(s) || f.province.toLowerCase().includes(s) || (f.prov || "").toLowerCase().includes(s));
  const provs = []; rows.forEach((f) => { if (!provs.includes(f.province)) provs.push(f.province); });
  return <div className="lk-overlay" onClick={onClose}><div className="lk-modal" onClick={(e) => e.stopPropagation()}>
    <div className="lk-search"><Spr id="i-search" size={20} /><input ref={ref} value={q} onChange={(e) => setQ(e.target.value)} placeholder="Switch facility — search hospitals by name or province…" /><span className="esc">ESC</span></div>
    <div className="lk-list">{rows.length === 0 ? <div className="lk-empty">No facilities match “{q}”.</div> : provs.map((pv) => <div key={pv}>
      <div className="lk-scope">{pv}</div>
      {rows.filter((f) => f.province === pv).map((f) => <button key={f.id} className={"lk-row" + (f.id === activeId ? " sel" : "")} onClick={() => onPick(f)}>
        <span className="lk-av" style={{ background: "var(--brand-l)", color: "var(--brand-d)" }}><Spr id="i-hospital" size={18} /></span>
        <span className="lr-main"><span className="lr-name">{f.facility}{f.id === activeId && <span className="badge ok">Current</span>}</span><span className="lr-id">{f.province} · {f.unit}</span></span>
        <span className="lr-right"><span className="lk-src-ct">{f.emr}</span></span>
      </button>)}
    </div>)}</div>
    <div className="lk-foot"><Spr id="i-shield" size={14} />Switching facility changes your working context · access stays role-controlled and audit-logged</div>
  </div></div>;
}

/* ---------- main app ---------- */
function PatientApp({ onSignOut, persona = { name: "Dr. Priya Sharma", title: "Emergency Medicine", initials: "PS", hue: 282 } } = {}) {
  const { patients, sources } = window.PT;
  const [activeId, setActiveId] = uS(patients[0].id);
  const [section, setSection] = uS("summary");
  const [prevSection, setPrevSection] = uS("summary");
  const SECTION_LABEL = { summary: "Summary", timeline: "Full timeline", meds: "Medications", imaging: "Imaging & reports", labs: "Labs", allergies: "Allergies", settings: "Settings" };
  const goSection = (s) => { if (s === "settings" && section !== "settings") setPrevSection(section); setSection(s); };
  const [lookup, setLookup] = uS(false);
  const [facOpen, setFacOpen] = uS(false);
  const [clinic, setClinic] = uS(window.PT.clinic);
  const [noteOpen, setNoteOpen] = uS(false);
  const [notes, setNotes] = uS([]);
  const [pop, setPop] = uS(false);
  const [askVal, setAskVal] = uS("");
  const [askAns, setAskAns] = uS(null);
  const [mAsk, setMAsk] = uS(false);
  const p = patients.find((x) => x.id === activeId) || patients[0];

  uE(() => { const h = (e) => { if ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === "k") { e.preventDefault(); setLookup(true); } }; window.addEventListener("keydown", h); return () => window.removeEventListener("keydown", h); }, []);
  uE(() => { setSection("summary"); setNotes([]); setPop(false); setAskAns(null); setMAsk(false); setNoteOpen(false); }, [activeId]);

  const tiles = safetyTiles(p);
  const responded = (p.connected || []).length;
  const acceptSummary = (text, edited) => {
    const body = text || (p.summary.prose || []).map((x) => x.t).join(" ");
    setNotes((n) => [...n, { who: persona.name, role: persona.title, tag: `${edited ? "Edited" : "Accepted"} AI summary · ${responded} of 4 sources`, body, ai: true, hue: persona.hue }]);
    setNoteOpen(true);
  };
  const postNote = (text) => setNotes((n) => [...n, { who: persona.name, role: persona.title, body: text, hue: persona.hue }]);
  function submitAsk() {
    const v = askVal.trim(); if (!v) return;
    const a = (p.summary.answers && p.summary.answers[v]) || "I answer only from this patient's connected records. Try a suggested question on the summary, or ask about meds, labs, or allergies.";
    setSection("summary"); setAskAns({ q: v, a }); setAskVal("");
  }

  return (
    <div className="mbx">
      <div dangerouslySetInnerHTML={{ __html: `<svg width="0" height="0" style="position:absolute" aria-hidden="true">${MBX_SPRITE}</svg>` }} />
      <div className="app">
        {/* RAIL */}
        <aside className="rail">
          <div className="brand">
            <img className="brand-logo" src="assets/medbridges-logo.png" alt="Med Bridges" />
            <div className="ico-row">
              <button className={"iconbtn" + (section === "settings" ? " active" : "")} title="Settings" onClick={() => goSection("settings")}><Spr id="i-sliders" size={16} /></button>
              {onSignOut && <button className="iconbtn" title="Switch role / sign out" onClick={onSignOut}><Spr id="i-logout" size={16} /></button>}
            </div>
          </div>
          <button className="locbtn" onClick={() => setFacOpen(true)}>
            <span className="pin"><Spr id="i-hospital" size={16} /></span>
            <div><div className="fac">{clinic.facility} · {clinic.prov}</div><div className="sub">{clinic.unit} · {persona.name}</div></div>
            <span className="chev"><Spr id="i-chevd" size={16} /></span>
          </button>
          <button className="find" onClick={() => setLookup(true)}><Spr id="i-search" size={16} /><span style={{ flex: 1, textAlign: "left" }}>Find a patient…</span><kbd>⌘K</kbd></button>
          <div className="curpat">
            <span className="cav" style={{ background: hueColor(p.avatarHue) }}>{initials(p)}</span>
            <div><div className="cn"><span className={"ad " + p.acuity} />{p.first} {p.last}</div><div className="cm">{p.age}{p.sex} · {p.origin}</div></div>
          </div>
          <div>
            <div className="navlabel">Patient record</div>
            <nav className="nav">
              {["summary", "timeline", "meds", "imaging", "labs", "allergies"].map((id) => {
                const labelMap = { summary: "Summary", timeline: "Full timeline", meds: "Medications", imaging: "Imaging & reports", labs: "Labs", allergies: "Allergies" };
                const showDot = id === "allergies" && (!(p.allergies || []).length || (p.allergies || []).some((a) => a.status !== "confirmed"));
                return <a key={id} className={section === id ? "active" : ""} onClick={() => setSection(id)}><Spr id={NAV_ICON[id]} /> {labelMap[id]}{showDot && <span className="dot" />}</a>;
              })}
            </nav>
          </div>
          <div>
            <div className="navlabel">Data sources · this patient</div>
            {SRC_ORDER.map((id) => { const s = sources[id]; const on = (p.connected || []).includes(id); return (
              <div className={"srcmini" + (on ? "" : " off")} key={id}>
                <span className="sd" style={{ background: on ? s.color : "var(--border-strong)" }} />
                <div><div className="nm">{s.name} — {s.org}</div><div className="mt">{s.span}</div></div>
                <span className={"stt " + (on ? "on" : "no")}>{on ? "live" : "no rec"}</span>
              </div>); })}
          </div>
          <div className="rail-foot"><Spr id="i-shield" size={16} /><span>Federated read-only access · every view audit-logged</span></div>
        </aside>

        {/* MAIN */}
        <div className="main">
          <div className="maincol">
            <div className="scroll">
              <div className="wrap">
                <nav className="crumbs">
                  {section !== "summary" && <button className="cr back" onClick={() => setSection(section === "settings" ? prevSection : "summary")}><Spr id="i-chevr" size={14} style={{ transform: "rotate(180deg)" }} />Back</button>}
                  <button className="cr" onClick={() => setFacOpen(true)}>{clinic.facility}</button>
                  <span className="sep">›</span>
                  <button className="cr" onClick={() => setSection("summary")}>{p.first} {p.last}</button>
                  <span className="sep">›</span>
                  <span className="cur">{SECTION_LABEL[section]}</span>
                </nav>
                {section === "settings" && typeof SettingsScreen !== "undefined" ? (
                  <SettingsScreen persona={persona} t={{ format: "bullets", accent: ["#1C5DAE"], density: "regular" }} setTweak={() => {}} appearanceControls={[]} accentOptions={[]} scope="clinician" onClose={() => setSection(prevSection)} />
                ) : (<>
                  {/* identity bar */}
                  <div className="idbar">
                    <span className="av" style={{ background: hueColor(p.avatarHue) }}>{initials(p)}</span>
                    <div>
                      <div style={{ display: "flex", alignItems: "center", gap: 11, flexWrap: "wrap" }}><h1>{p.first} {p.last}, {p.age}{p.sex}</h1><span className={"acuity " + p.acuity}><span className="d" />{ACUITY_LABEL[p.acuity]}</span></div>
                      <div className="meta">DOB {p.dob} · Health card <b className="tnum">{p.hcn}</b> · {p.origin}</div>
                    </div>
                    <div className="idright">
                      <span className="transfer">{p.origin}<Spr id="i-chevr" size={14} />{clinic.facility} · {p.arriving}</span>
                      <button className="datapic" onClick={() => setPop(true)}><Spr id="i-database" size={16} />{responded} of 4 systems · {responded < 4 ? <span className="warnflag"><i />{4 - responded} no match</span> : "all responded"}</button>
                      <button className="noteBtn" onClick={() => setNoteOpen((o) => !o)}><Spr id="i-note" size={16} />Care-team note{notes.length > 0 && <span className="ct">{notes.length}</span>}</button>
                    </div>
                  </div>

                  {section === "summary" && <>
                    <SecH>Safety check — is it safe to act?</SecH>
                    <div className="band">{tiles.map((t) => <div key={t.key} className={"safe " + t.cls} onClick={() => t.to ? setSection(t.to) : setPop(true)}>
                      <div className="lab"><Spr id={t.ic} /><span>{t.lab}</span></div>
                      <div className="val">{t.val}</div><span className="chip">{t.chip}</span><div className="note">{t.note}</div>
                    </div>)}</div>
                    <SecH>Summary across connected systems</SecH>
                    <AISummary p={p} onAccept={acceptSummary} />
                    {askAns && <div className="ans" style={{ margin: "12px 2px 0" }}><b>{askAns.q}</b><br />{askAns.a}</div>}
                    <SecH>Recent history</SecH>
                    {(p.timeline || []).length ? <div className="tl">{(p.timeline || []).slice(0, 5).map((e, i) => <TlRow key={i} e={e} />)}</div> : <Empty ic="i-clock" t="No dated history returned" n="No connected system returned dated encounters for this patient." />}
                    {(p.timeline || []).length > 5 && <div style={{ display: "flex", justifyContent: "center", marginTop: 14 }}><button className="btn" onClick={() => setSection("timeline")}><Spr id="i-chevd" size={14} />View full timeline ({p.timeline.length} events)</button></div>}
                  </>}
                  {section === "timeline" && <><SecH>Full longitudinal timeline</SecH><TimelineFull p={p} /></>}
                  {section === "meds" && <><SecH>Active medications</SecH><MedsView p={p} /></>}
                  {section === "imaging" && <><SecH>Imaging & reports</SecH><ImagingView p={p} /></>}
                  {section === "labs" && <><SecH>Recent labs</SecH><LabsView p={p} /></>}
                  {section === "allergies" && <><SecH>Allergies</SecH><AllergiesView p={p} /></>}
                </>)}
              </div>
            </div>
            {/* docked ask bar */}
            {section !== "settings" && <div className="ask">
              <div className="ask-in">
                <span className="sp"><Spr id="i-spark" /></span>
                <input value={askVal} onChange={(e) => setAskVal(e.target.value)} onKeyDown={(e) => { if (e.key === "Enter") { e.preventDefault(); submitAsk(); } }} placeholder={`Ask about ${p.first} — grounded in connected records`} />
                <button className="go" onClick={submitAsk}><Spr id="i-send" size={16} style={{ stroke: "#fff" }} /></button>
              </div>
              <div className="ask-hint">Grounded in connected records · ⌘K to switch patient</div>
            </div>}
          </div>

          {/* care-team note */}
          <aside className={"notepanel" + (noteOpen ? " open" : "")}>
            <div className="np-head">
              <span className="npic"><Spr id="i-note" size={16} /></span>
              <div><div className="t">Care-team note</div><div className="s"><Spr id="i-shield" size={14} />Lives in MedBridge · shared with the care team · audit-logged</div></div>
              <button className="close" onClick={() => setNoteOpen(false)}><Spr id="i-x" size={20} /></button>
            </div>
            <div className="np-body">
              {notes.length === 0 ? <div className="np-empty">No care-team notes yet.<br />Accept the AI summary or post a note below — it stays in MedBridge and never writes back to the source EMRs.</div>
                : notes.map((e, i) => <div className={"nentry" + (e.ai ? " ai" : "")} key={i}>
                  <div className="nmeta"><span className="nav" style={{ background: hueColor(e.hue || 282) }}>{(e.who || "?").split(" ").map((w) => w[0]).join("").slice(-2)}</span><div><div className="nwho">{e.who}</div><div className="nrole">{e.role}</div></div><span className="ntime">just now</span></div>
                  {e.tag && <span className="badge brand ntag">{e.tag}</span>}
                  <div className="nbody">{e.body}</div>
                </div>)}
            </div>
            <NoteCompose persona={persona} onPost={postNote} />
          </aside>
        </div>
      </div>

      {/* ---------- MOBILE shell (CSS shows this ≤760px, hides .app) ---------- */}
      <div className="mapp">
        <div className="mhead">
          <button className="miconbtn" onClick={() => section === "summary" ? setLookup(true) : setSection("summary")}><Spr id={section === "summary" ? "i-search" : "i-chevr"} size={18} style={section === "summary" ? null : { transform: "rotate(180deg)" }} /></button>
          <span className="mav" style={{ background: hueColor(p.avatarHue) }}>{initials(p)}</span>
          <div style={{ flex: 1, minWidth: 0 }}><div className="mh1">{p.first} {p.last}, {p.age}{p.sex}</div><div className="mhsub">DOB {p.dob} · {p.origin}</div></div>
          <button className="miconbtn" onClick={() => setNoteOpen(true)} style={{ position: "relative" }}><Spr id="i-note" size={18} />{notes.length > 0 && <span className="mct">{notes.length}</span>}</button>
          <span className={"acuity " + p.acuity}><span className="d" />{ACUITY_LABEL[p.acuity]}</span>
        </div>
        <div className="mctx">
          <span className="transfer">{p.origin} <Spr id="i-chevr" size={13} /> {clinic.facility}</span>
          <button className="mdatapic" onClick={() => setPop(true)}><Spr id="i-signaloff" size={16} /><span>Data picture · {responded} of 4 systems responded</span><Spr id="i-chevr" size={16} /></button>
        </div>
        <div className="mscroll">
          {section === "settings" && typeof SettingsScreen !== "undefined" ? (
            <SettingsScreen persona={persona} t={{ format: "bullets", accent: ["#1C5DAE"], density: "regular" }} setTweak={() => {}} appearanceControls={[]} accentOptions={[]} scope="clinician" onClose={() => setSection(prevSection)} />
          ) : section === "summary" ? (<>
            <div className="meyebrow">Safety check — is it safe to act?</div>
            <div className="mband">{tiles.map((t) => <div key={t.key} className={"msafe " + t.cls} onClick={() => t.to ? setSection(t.to) : setPop(true)}>
              <span className="mi"><Spr id={t.ic} size={20} /></span>
              <div className="mt"><div className="mlab">{t.lab}</div><div className="mval">{t.val}</div><div className="mnote">{t.note}</div></div>
              <span className="mchip">{t.chip}</span>
            </div>)}</div>
            <div style={{ marginTop: 18 }}><AISummary p={p} onAccept={acceptSummary} /></div>
            {askAns && <div className="ans" style={{ margin: "12px 0 0" }}><b>{askAns.q}</b><br />{askAns.a}</div>}
            <div className="meyebrow" style={{ marginTop: 18 }}>Recent history</div>
            {(p.timeline || []).slice(0, 5).map((e, i) => <TlRow key={i} e={e} />)}
          </>) : section === "timeline" ? <><SecH>Full timeline</SecH><TimelineFull p={p} /></>
            : section === "meds" ? <><SecH>Medications</SecH><MedsView p={p} /></>
            : section === "imaging" ? <><SecH>Imaging & reports</SecH><ImagingView p={p} /></>
            : section === "labs" ? <><SecH>Labs</SecH><LabsView p={p} /></>
            : section === "allergies" ? <><SecH>Allergies</SecH><AllergiesView p={p} /></> : null}
        </div>
        {section !== "settings" && <button className="fab" onClick={() => setMAsk(true)}><Spr id="i-spark" size={20} style={{ stroke: "#fff" }} />Ask AI</button>}
        <nav className="tabbar">
          {[["summary", "Summary", "i-spark"], ["timeline", "Timeline", "i-clock"], ["meds", "Meds", "i-pill"], ["imaging", "Imaging", "i-image"], ["labs", "Labs", "i-flask"], ["allergies", "Allergies", "i-alert"]].map(([id, label, ic]) => {
            const dot = id === "allergies" && (!(p.allergies || []).length || (p.allergies || []).some((a) => a.status !== "confirmed"));
            return <button key={id} className={"tab" + (section === id ? " active" : "")} onClick={() => setSection(id)}><span className="dotwrap"><Spr id={ic} size={20} />{dot && <span className="tdot" />}</span>{label}</button>;
          })}
        </nav>
        {noteOpen && <div className="notescreen open">
          <div className="ns-head"><button className="miconbtn" onClick={() => setNoteOpen(false)}><Spr id="i-chevr" size={18} style={{ transform: "rotate(180deg)" }} /></button><div><div className="nstitle">Care-team note</div><div className="nssub"><Spr id="i-shield" size={13} />Lives in MedBridge · audit-logged</div></div></div>
          <div className="ns-body">{notes.length === 0 ? <div className="np-empty">No care-team notes yet. Accept the AI summary or post a note below.</div>
            : notes.map((e, i) => <div className={"nentry" + (e.ai ? " ai" : "")} key={i}><div className="nmeta"><span className="nav" style={{ background: hueColor(e.hue || 282) }}>{(e.who || "?").split(" ").map((w) => w[0]).join("").slice(-2)}</span><div><div className="nwho">{e.who}</div><div className="nrole">{e.role}</div></div><span className="ntime">just now</span></div>{e.tag && <span className="badge brand ntag">{e.tag}</span>}<div className="nbody">{e.body}</div></div>)}</div>
          <NoteCompose persona={persona} onPost={postNote} />
        </div>}
        {mAsk && <><div className="sheet-bd show" onClick={() => setMAsk(false)} /><div className="sheet show">
          <div className="grab" /><h4><Spr id="i-spark" size={16} />Ask about {p.first}</h4>
          <div className="psub">Grounded in this patient's connected records</div>
          <div style={{ display: "flex", flexWrap: "wrap", gap: 8, marginTop: 10 }}>{(p.summary.chips || []).map((c, i) => <button key={i} className="chip-q" onClick={() => { setAskAns({ q: c, a: (p.summary.answers && p.summary.answers[c]) || "—" }); setSection("summary"); setMAsk(false); }}>{c}</button>)}</div>
        </div></>}
      </div>

      {pop && <><div className="backdrop" onClick={() => setPop(false)} /><div className="pop">
        <h4><Spr id="i-database" size={16} />Data picture for {p.first} {p.last}</h4>
        <div className="psub">Discovered per-patient · pulled live · nothing copied or stored centrally</div>
        {dataRows(p).map(({ s, on, unreachable }) => <div className="srcrow" key={s.id}>
          <span className="sd" style={{ background: on ? s.color : "var(--gap)" }} />
          <div><div className="sn">{s.name} — {s.org}</div><div className="sm">{on ? "Responded · FHIR R4" : unreachable ? "No reachable endpoint" : "No record returned"}</div></div>
          {on ? <span className="st live"><i />responded</span> : <span className="st no"><Spr id="i-signaloff" size={14} />{unreachable ? "unreachable" : "no record"}</span>}
        </div>)}
        <div className="pfoot"><Spr id="i-shield" size={14} />Access role-controlled & audit-logged · sources sorted by clinical relevance</div>
      </div></>}

      {lookup && <Lookup activeId={activeId} onPick={(id) => { setActiveId(id); setLookup(false); }} onClose={() => setLookup(false)} />}
      {facOpen && <FacilityPicker activeId={clinic.id} onPick={(f) => { const next = Object.assign({}, f, { network: clinic.network }); setClinic(next); window.PT.clinic = next; setFacOpen(false); }} onClose={() => setFacOpen(false)} />}
    </div>
  );
}

function NoteCompose({ persona, onPost }) {
  const [v, setV] = uS("");
  function post() { const t = v.trim(); if (!t) return; onPost(t); setV(""); }
  return <div className="np-foot">
    <textarea className="np-compose" value={v} onChange={(e) => setV(e.target.value)} onKeyDown={(e) => { if (e.key === "Enter" && !e.shiftKey) { e.preventDefault(); post(); } }} placeholder="Add to the care-team note…" />
    <div className="np-cf"><span className="who"><Spr id="i-shield" size={14} />Posting as {persona.name} · visible to care team</span><button className="btn primary sm" style={{ marginLeft: "auto" }} onClick={post}><Spr id="i-send" size={14} />Post</button></div>
  </div>;
}

Object.assign(window, { PatientApp });
if (!window.__MB_EMBED) ReactDOM.createRoot(document.getElementById("root")).render(<PatientApp />);
