/* MedBridge — Transfer events: list + detail + AI handoff summary */

/* ---------- AI handoff summary ---------- */
function AISummary({ t }) {
  const [text, setText] = useStateMB("");
  const [shown, setShown] = useStateMB(0);
  const [loading, setLoading] = useStateMB(true);
  const [err, setErr] = useStateMB(false);

  const present = window.MB.FIELDS.filter((f) => t.fields[f.key]).map((f) => `${f.label}: ${t.fields[f.key]}`);
  const missing = window.MB.FIELDS.filter((f) => !t.fields[f.key]);
  const missCrit = missing.filter((f) => f.critical).map((f) => f.label);
  const missOther = missing.filter((f) => !f.critical).map((f) => f.label);

  function fallback() {
    const sbar = `${t.age} ${t.sex === "M" ? "male" : "female"} transferring ${t.route.toLowerCase()} from ${t.from.fac} to ${t.to.fac} with ${t.dx}. Received data: ${present.map((p) => p.split(": ")[0]).join(", ") || "none"}.`;
    const risk = missCrit.length
      ? `${missCrit.join(", ")} ${missCrit.length > 1 ? "are" : "is"} not available at handoff — the receiving team cannot safely verify ${missCrit.map((m) => m.toLowerCase()).join(" or ")} before placing orders. Confirm verbally before arrival.`
      : `All critical fields present. Lower-priority gaps: ${missOther.join(", ") || "none"}.`;
    return sbar + "\n\n" + risk;
  }

  useEffectMB(() => {
    let cancel = false;
    setLoading(true); setErr(false); setText(""); setShown(0);
    const prompt = `You are a clinical informatics assistant generating a concise handoff summary for a receiving care team at a hospital patient transfer. All patient data is de-identified.

Transfer: ${t.route}, from ${t.from.fac} (${t.from.emr}) to ${t.to.fac} (${t.to.emr}).
Patient: ${t.age} age band, ${t.sex}. Working diagnosis: ${t.dx} (${t.dxCat}).
Structured data fields RECEIVED via FHIR:
${present.length ? present.map((p) => "- " + p).join("\n") : "- (none received)"}
Fields MISSING / not transmitted:
${missing.map((f) => "- " + f.label + (f.critical ? " [CRITICAL]" : "")).join("\n")}

Write two short paragraphs of plain prose. Absolute formatting rules: do NOT use markdown, asterisks, bold, headings, bullet points, or the literal words "Paragraph" or numbering. Just two paragraphs separated by one blank line.
First paragraph: a 2-3 sentence SBAR-style clinical handoff summary using ONLY the received data.
Second paragraph: begin with the exact word "Risk:" and then, in 1-2 sentences, state the specific clinical risk created by the missing critical fields and the concrete action the receiving team should take. If no critical fields are missing, say the information is adequate and note any minor gaps.
Keep it under 110 words total.`;

    const clean = (s) => (s || "")
      .replace(/\*\*/g, "").replace(/\*/g, "")
      .replace(/^\s*#+\s*/gm, "")
      .replace(/^\s*paragraph\s*\d*\s*[:.\-]?\s*/gim, "")
      .replace(/\n{3,}/g, "\n\n").trim();

    (async () => {
      try {
        if (!window.claude || !window.claude.complete) throw new Error("no-api");
        const out = await window.claude.complete(prompt);
        if (cancel) return;
        const cleaned = clean(out);
        setText(cleaned || fallback());
      } catch (e) {
        if (cancel) return;
        setErr(true); setText(fallback());
      } finally { if (!cancel) setLoading(false); }
    })();
    return () => { cancel = true; };
  }, [t.id]);

  // typewriter reveal
  useEffectMB(() => {
    if (loading || !text) return;
    setShown(0);
    const id = setInterval(() => setShown((s) => { if (s >= text.length) { clearInterval(id); return s; } return s + 3; }), 12);
    return () => clearInterval(id);
  }, [text, loading]);

  const paras = text.slice(0, shown).split("\n\n");
  return (
    <div className="ai-panel">
      <div className="ai-head">
        <span className="ai-spark"><Icon name="activity" size={17} /></span>
        <div className="grow">
          <div className="fw7" style={{ fontSize: 13 }}>AI handoff summary</div>
          <div className="muted" style={{ fontSize: 11.5 }}>Generated from received FHIR fields · de-identified{err ? " · offline mode" : ""}</div>
        </div>
        <span className="badge badge-purple">claude-haiku</span>
      </div>
      <div className="ai-body">
        {loading ? (
          <div className="row gap8 muted" style={{ fontSize: 13 }}>
            <span className="ai-dots"><span></span><span></span><span></span></span>
            Reading {present.length} received field{present.length !== 1 ? "s" : ""}, composing summary…
          </div>
        ) : (
          paras.map((p, i) => {
            const isRisk = p.toLowerCase().startsWith("risk:");
            return <p key={i} style={isRisk ? { color: "var(--mb-crit)", fontWeight: 500, background: "var(--mb-crit-bg)", padding: "9px 11px", borderRadius: 8 } : null}>
              {isRisk ? <><strong style={{ color: "var(--mb-crit)" }}>Risk: </strong>{p.slice(5).trim()}</> : p}
              {i === paras.length - 1 && shown < text.length && <span className="ai-cursor" />}
            </p>;
          })
        )}
      </div>
    </div>
  );
}

/* ---------- transfer detail ---------- */
function EmrTag({ emr, status }) {
  const dot = status === "sandbox" ? "sandbox" : "on";
  return <span className="row gap6" style={{ fontSize: 11.5, fontWeight: 600, color: "var(--text-2)" }}><span className={`sdot sdot-${dot}`} />{emr}</span>;
}

function TransferDetail({ t, onBack }) {
  const { fmtDT, ago } = window.MB.util;
  const timeline = [
    { ic: "inbox", label: "HL7 v2 ADT^A02 received", detail: `Transfer event from ${t.from.fac}`, at: t.ts },
    { ic: "send", label: "FHIR R4 completeness query issued", detail: "8 fields requested · OAuth2 / SMART", at: new Date(t.ts.getTime() + 8000) },
    { ic: "activity", label: `Scored ${t.score}% complete`, detail: `${window.MB.FIELDS.filter((f) => t.fields[f.key]).length}/8 fields present · identifiers discarded`, at: new Date(t.ts.getTime() + 26000) },
  ];
  if (t.outcome30) timeline.push({ ic: t.outcome30.complication ? "alert" : "check", label: t.outcome30.complication ? "30-day complication flagged" : "30-day follow-up — no complication", detail: t.outcome30.complication ? `${t.outcome30.label} (${t.outcome30.code})` : "Attribution: negative", at: new Date(t.ts.getTime() + 30 * 864e5), future: true });

  return (
    <div className="content"><div className="pad" style={{ maxWidth: 1080, margin: "0 auto" }}>
      <button className="row gap6 muted" onClick={onBack} style={{ fontSize: 12.5, fontWeight: 600, marginBottom: 14 }}><Icon name="chevL" size={15} />All transfers</button>

      <div className="page-head" style={{ marginBottom: 16 }}>
        <div>
          <div className="row gap10" style={{ marginBottom: 4 }}>
            <h1 style={{ fontSize: 20, whiteSpace: "nowrap" }} className="mono">{t.id}</h1>
            <RouteBadge route={t.route} />
            {t.status === "Completed" ? <Badge kind="neutral">Completed</Badge> : <Badge kind="warn" icon="clock">{t.status}</Badge>}
            {t.ocap && <Badge kind="purple" icon="shield">OCAP</Badge>}
          </div>
          <div className="ph-sub">{t.age} · {t.sex} · {t.dx} · detected {ago(t.ts)} · <span className="muted">no patient identifiers retained</span></div>
        </div>
        <div className="row gap14">
          <div className="bigstat"><div className="bs-v" style={{ color: scoreColor(t.score) }}>{t.score}%</div><div className="bs-l">{window.MB.scoreWord(t.score)}</div></div>
        </div>
      </div>

      {/* flow */}
      <Card style={{ marginBottom: 16 }}>
        <div className="flow">
          <div className="flow-node">
            <div className="muted" style={{ fontSize: 10.5, fontWeight: 700, textTransform: "uppercase", letterSpacing: ".05em", marginBottom: 5 }}>Sending</div>
            <div className="fw7" style={{ fontSize: 14 }}>{t.from.fac}</div>
            <div className="muted" style={{ fontSize: 12, marginBottom: 7 }}>{t.from.city}</div>
            <EmrTag emr={t.from.emr} />
          </div>
          <div className="flow-arrow"><span className="fa-label">{t.route.includes("medevac") ? "MEDEVAC" : "TRANSFER"}</span><Icon name="chevR" size={26} /></div>
          <div className="flow-node" style={{ borderColor: "var(--primary-mid)", background: "var(--primary-light)" }}>
            <div className="muted" style={{ fontSize: 10.5, fontWeight: 700, textTransform: "uppercase", letterSpacing: ".05em", marginBottom: 5 }}>Receiving</div>
            <div className="fw7" style={{ fontSize: 14 }}>{t.to.fac}</div>
            <div className="muted" style={{ fontSize: 12, marginBottom: 7 }}>{t.to.city}</div>
            <EmrTag emr={t.to.emr} status={t.to.emr === "Epic" ? "sandbox" : "on"} />
          </div>
        </div>
      </Card>

      {/* critical banner */}
      {t.missCrit.length > 0 && (
        <div className="row gap10" style={{ padding: "13px 16px", borderRadius: 11, background: "var(--mb-crit-bg)", border: "1px solid #F0C9C4", marginBottom: 16 }}>
          <Icon name="alert" size={20} style={{ color: "var(--mb-crit)", flexShrink: 0 }} />
          <div className="grow" style={{ fontSize: 13 }}><b style={{ color: "var(--mb-crit)" }}>Critical fields missing at transfer:</b> <b>{t.missCrit.join(", ")}</b>. Receiving team alerted{t.status !== "Completed" ? " — flagged before patient departure window closes." : "."}</div>
        </div>
      )}

      {/* AI summary */}
      <div style={{ marginBottom: 16 }}><AISummary t={t} /></div>

      {/* field grid */}
      <Card title="8-field completeness breakdown" icon="grid"
        action={<span className="muted" style={{ fontSize: 11.5 }}>{window.MB.FIELDS.filter((f) => t.fields[f.key]).length} of 8 present</span>}>
        <FieldGrid fields={t.fields} />
      </Card>

      {/* timeline + meta */}
      <div style={{ display: "grid", gridTemplateColumns: "1.4fr 1fr", gap: 16, marginTop: 16, alignItems: "start" }}>
        <Card title="Scoring timeline" icon="clock">
          <div className="col">
            {timeline.map((s, i) => (
              <div key={i} className="row gap10" style={{ alignItems: "flex-start", paddingBottom: i < timeline.length - 1 ? 14 : 0 }}>
                <div className="col" style={{ alignItems: "center" }}>
                  <span style={{ width: 28, height: 28, borderRadius: 8, display: "grid", placeItems: "center", background: s.ic === "alert" ? "var(--mb-crit-bg)" : s.ic === "check" ? "var(--mb-good-bg)" : "var(--primary-light)", color: s.ic === "alert" ? "var(--mb-crit)" : s.ic === "check" ? "var(--mb-good)" : "var(--primary)", flexShrink: 0 }}><Icon name={s.ic} size={15} /></span>
                  {i < timeline.length - 1 && <span style={{ width: 2, flex: 1, minHeight: 18, background: "var(--hairline)", marginTop: 2 }} />}
                </div>
                <div style={{ paddingTop: 3 }}>
                  <div className="fw6" style={{ fontSize: 12.5 }}>{s.label}</div>
                  <div className="muted" style={{ fontSize: 11.5 }}>{s.detail}</div>
                  <div className="muted mono" style={{ fontSize: 10.5, marginTop: 1 }}>{s.future ? "projected · " : ""}{fmtDT(s.at)}</div>
                </div>
              </div>
            ))}
          </div>
        </Card>
        <Card title="Privacy & retention" icon="shield">
          <div className="col gap10" style={{ fontSize: 12.5 }}>
            <div className="row gap8"><Icon name="check" size={15} style={{ color: "var(--mb-good)" }} /><span>Tier 2 data read in real time, <b>never stored</b></span></div>
            <div className="row gap8"><Icon name="check" size={15} style={{ color: "var(--mb-good)" }} /><span>Only the de-identified score is retained (Tier 3)</span></div>
            <div className="row gap8"><Icon name="check" size={15} style={{ color: "var(--mb-good)" }} /><span>Federated query — record stays at {t.from.fac.split(" — ")[0]}</span></div>
            <div className="divider" style={{ margin: "4px 0" }}></div>
            <div className="sb-row"><span className="k muted">Encounter type</span><span className="v">{t.route}</span></div>
            <div className="sb-row"><span className="k muted">Diagnosis category</span><span className="v">{t.dxCat}</span></div>
            <div className="sb-row"><span className="k muted">Retained identifiers</span><span className="v" style={{ color: "var(--mb-good)" }}>None</span></div>
          </div>
        </Card>
      </div>
    </div></div>
  );
}

/* ---------- transfer list ---------- */
function TransferList({ openTransfer }) {
  const { transfers } = window.MB;
  const [status, setStatus] = useStateMB("All");
  const [route, setRoute] = useStateMB("All");
  const [q, setQ] = useStateMB("");

  let rows = transfers.filter((t) => (status === "All" || (status === "Active" ? t.status !== "Completed" : t.status === "Completed")) && (route === "All" || t.route === route));
  if (q.trim()) { const s = q.toLowerCase(); rows = rows.filter((t) => t.id.toLowerCase().includes(s) || t.dx.toLowerCase().includes(s) || t.from.fac.toLowerCase().includes(s) || t.to.fac.toLowerCase().includes(s)); }
  rows = [...rows].sort((a, b) => b.ts - a.ts);
  const routes = ["All", "Inter-provincial medevac", "Inter-facility", "Intra-hospital", "Hospital → LTC"];

  const Chip = ({ active, onClick, children }) => (
    <button onClick={onClick} className="btn btn-sm" style={{ background: active ? "var(--primary)" : "var(--surface)", color: active ? "#fff" : "var(--text-2)", border: "1px solid " + (active ? "var(--primary)" : "var(--border)") }}>{children}</button>
  );

  return (
    <div className="content"><div className="pad" style={{ maxWidth: 1480, margin: "0 auto" }}>
      <div className="page-head">
        <div><h1>Care Transitions</h1><div className="ph-sub">{transfers.length} scored events · live across connected jurisdictions</div></div>
        <div className="search" style={{ width: 280 }}><span className="s-ic"><Icon name="search" size={16} /></span><input placeholder="Search ID, diagnosis, facility…" value={q} onChange={(e) => setQ(e.target.value)} /></div>
      </div>

      <div className="row" style={{ justifyContent: "space-between", marginBottom: 14, flexWrap: "wrap", gap: 10 }}>
        <div className="row gap6">
          <Chip active={status === "All"} onClick={() => setStatus("All")}>All</Chip>
          <Chip active={status === "Active"} onClick={() => setStatus("Active")}>In transit</Chip>
          <Chip active={status === "Completed"} onClick={() => setStatus("Completed")}>Completed</Chip>
        </div>
        <div className="row gap6" style={{ flexWrap: "wrap" }}>
          {routes.map((r) => <Chip key={r} active={route === r} onClick={() => setRoute(r)}>{r === "All" ? "All routes" : r.replace("Inter-provincial ", "")}</Chip>)}
        </div>
      </div>

      <div className="card" style={{ overflow: "hidden" }}>
        <table className="tbl">
          <thead><tr><th>Encounter</th><th>Route</th><th>Sending → Receiving</th><th>Diagnosis</th><th>8-field</th><th>Score</th><th>30-day</th><th style={{ textAlign: "right" }}>When</th><th></th></tr></thead>
          <tbody>
            {rows.map((t) => (
              <tr key={t.id} style={{ cursor: "pointer" }} onClick={() => openTransfer(t.id)}>
                <td className="mono fw6" style={{ fontSize: 12 }}>{t.id}<div className="muted" style={{ fontSize: 10.5, fontWeight: 400 }}>{t.age} · {t.sex}</div></td>
                <td><RouteBadge route={t.route} /></td>
                <td style={{ maxWidth: 260 }}><div className="fw6" style={{ fontSize: 12 }}>{t.from.fac.split(" — ")[0].split(" (")[0]}</div><div className="muted" style={{ fontSize: 11 }}>→ {t.to.fac.split(" — ")[0].split(" (")[0]}, {t.to.city.split(",")[1] || t.to.city}</div></td>
                <td style={{ fontSize: 12.5 }} className="fw6">{t.dxCat}</td>
                <td><FieldStrip fields={t.fields} />{t.missCrit.length > 0 && <div style={{ fontSize: 10, color: "var(--mb-crit)", fontWeight: 700, marginTop: 3 }}>missing {t.missCrit.join(", ")}</div>}</td>
                <td><ScorePill score={t.score} /></td>
                <td>{t.outcome30 ? (t.outcome30.complication ? <Badge kind="critical" icon="alert">Complication</Badge> : <Badge kind="good" icon="check">Clear</Badge>) : <span className="muted" style={{ fontSize: 11.5 }}>pending</span>}</td>
                <td className="muted mono" style={{ textAlign: "right", fontSize: 11.5 }}>{window.MB.util.ago(t.ts)}</td>
                <td><Icon name="chevR" size={15} className="muted" /></td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>
    </div></div>
  );
}

Object.assign(window, { AISummary, TransferDetail, TransferList });
