/* Pharmacy — the medication orders on charts, and the stock behind them.
   Commit model: INSTANT on both screens. Verifying, holding, resuming and
   recording a dose apply immediately with an undo toast; stopping a course is
   irreversible and opens a confirm dialog from App.jsx. Creating an order or a
   formulary line is a staged dialog.

   The ward control is a SCOPE filter (§5.3): it is above the figures and moves
   them. The text and status filters are inside the list container and narrow the
   list only — the figures do not move with them. */
(() => {
  const {
    Button, Badge, Select, Alert, AlertTitle, AlertDescription,
    Table, TableHeader, TableBody, TableRow, TableHead, TableCell,
  } = window.OriginDesignSystem_7c998b;

  const MED_STATUS_FILTER = [{ value: "all", label: "All statuses" }].concat(MEDICATION_STATUS.map((s) => ({ value: s.id, label: s.label })));
  const SCOPE_WARDS = [{ value: "all", label: "Every ward" }].concat(WARDS.map((w) => ({ value: w.value, label: wardName(w.value) })));

  function MedicationScreen({ data, now, viewer, ward, onWardChange, onNavigate, onMedicationTransition, onNewOrder, onExport }) {
    const [query, setQuery] = React.useState("");
    const [status, setStatus] = React.useState("all");
    const { sort, onSort } = useSort("next", "asc");

    const wardOf = (order) => {
      const admission = admissionOfPatient(data.admissions, order.patientId);
      return admission ? admission.ward : null;
    };
    /* Scoped first: every figure below is computed from this array. */
    const scoped = ward === "all" ? data.orders : data.orders.filter((o) => wardOf(o) === ward);
    const awaiting = ordersAwaitingPharmacy(scoped);
    const due = dosesDue(scoped, now);
    const missed = dosesMissed(scoped, now);
    const active = activeOrders(scoped);

    const dirty = !!query || status !== "all";
    const clear = () => { setQuery(""); setStatus("all"); };
    const filtered = scoped.filter((order) => {
      if (status !== "all" && order.status !== status) return false;
      if (query) {
        const q = query.toLowerCase();
        const patient = patientById(data.patients, order.patientId);
        if ((order.drug + " " + order.indication + " " + patient.name + " " + patient.number).toLowerCase().indexOf(q) < 0) return false;
      }
      return true;
    });
    const rows = sortRows(filtered, sort, {
      next: (o) => o.nextDoseAt || Infinity,
      patient: (o) => patientById(data.patients, o.patientId).name,
      drug: (o) => o.drug,
    });

    return (
      <>
        <PageHeader
          path="/medication"
          title="Medication orders"
          sub={"Everything prescribed at " + HD_HOSPITAL.short + ". A pharmacist has to verify an order before the first dose can be given."}
          actions={
            <>
              <ExportMenu scope={ward === "all" ? "All " + data.orders.length + " orders" : scoped.length + " orders on " + wardName(ward)}
                onExport={(format) => onExport("Medication administration record", ward === "all" ? "All wards" : wardName(ward) + " ward", scoped.length, format)} />
              <Button size="sm" onClick={onNewOrder}><Icon name="plus" />New order</Button>
            </>
          }
        />
        <div className="hd-band" style={{ display: "flex", flexWrap: "wrap", alignItems: "center", gap: "var(--space-2) var(--space-4)" }}>
          <span className="hd-fig__label">Ward</span>
          <span className="hd-filters__select"><Select size="sm" aria-label="Scope the figures and the list to one ward" items={SCOPE_WARDS} value={ward} onValueChange={onWardChange} /></span>
          <p className="hd-band__note" style={{ flex: 1, minWidth: "16rem" }}>
            {ward === "all"
              ? "Counting every order in the hospital, on any ward and none."
              : "Counting the " + scoped.length + " orders whose patient is on " + wardName(ward) + " ward."}
          </p>
          {ward !== "all" ? <Button variant="ghost" size="sm" onClick={() => onWardChange("all")}>Reset scope</Button> : null}
        </div>

        <Figures items={[
          { label: "Awaiting a pharmacist", value: awaiting.length, qualifier: awaiting.filter((o) => (drugById(data.formulary, o.drugId) || {}).stock === "out").length + " of them for a drug that is out of stock" },
          { label: "Doses due within the hour", value: due.length, qualifier: due.length ? "next at " + formatWhen(due.slice().sort((a, b) => a.nextDoseAt - b.nextDoseAt)[0].nextDoseAt, now) : "nothing on the clock" },
          { label: "Doses missed", value: missed.length, qualifier: missed.length ? "overdue by more than an hour" : "every due dose has gone in" },
          { label: "Active courses", value: active.length, qualifier: ordersOnHold(scoped).length + " further courses are on hold" },
        ]} />

        {missed.length ? (
          <div className="hd-alertwrap">
            <Alert variant="warning">
              <AlertTitle>{missed.length === 1 ? "One dose is overdue" : missed.length + " doses are overdue"}</AlertTitle>
              <AlertDescription>
                {missed.map((o) => patientName(data.patients, o.patientId) + " — " + o.drug + " " + o.dose + ", due " + formatWhen(o.nextDoseAt, now)).join(" · ")}. Recording the dose clears it.
              </AlertDescription>
            </Alert>
          </div>
        ) : null}

        <Band flush title={"Orders (" + scoped.length + ")"} note={ward === "all" ? "Every order in the hospital." : "Orders for patients on " + wardName(ward) + " ward."}>
          <FilterBar query={query} onQuery={setQuery} placeholder="Search drug, indication or patient…" dirty={dirty} onClear={clear}
            selects={[{ id: "status", label: "Status", items: MED_STATUS_FILTER, value: status, onChange: setStatus }]} />
          {rows.length === 0 ? <NoResults noun="orders" onClear={clear} /> : (
            <>
              <TableWrap>
                <Table>
                  <TableHeader>
                    <TableRow>
                      <TableHead><SortHead label="Patient" sortKey="patient" sort={sort} onSort={onSort} /></TableHead>
                      <TableHead><SortHead label="Drug" sortKey="drug" sort={sort} onSort={onSort} /></TableHead>
                      <TableHead>Dose</TableHead>
                      <TableHead>Status</TableHead>
                      <TableHead><SortHead label="Next dose" sortKey="next" sort={sort} onSort={onSort} /></TableHead>
                      <TableHead>Verified by</TableHead>
                      <TableHead>Action</TableHead>
                    </TableRow>
                  </TableHeader>
                  <TableBody>
                    {rows.map((order) => {
                      const patient = patientById(data.patients, order.patientId);
                      const drug = drugById(data.formulary, order.drugId);
                      return (
                        <TableRow key={order.id}>
                          <TableCell>
                            <PersonCell name={patient.name} avatar={patient.avatar} size={24}
                              meta={(wardOf(order) ? wardName(wardOf(order)) : "Not on a ward") + " · " + patient.number}
                              onOpen={() => onNavigate("/patients/" + patient.id)} />
                          </TableCell>
                          <TableCell>
                            <span className="hd-person__text">
                              <span className="hd-person__name">{order.drug}</span>
                              <span className="hd-person__meta">{order.indication}</span>
                            </span>
                          </TableCell>
                          <TableCell>{order.dose} · {labelOf(DRUG_ROUTES, order.route)} · {order.frequency.toLowerCase()}</TableCell>
                          <TableCell>
                            <span className="hd-actions__row">
                              <StatusBadge values={MEDICATION_STATUS} value={order.status} />
                              {drug && drug.stock === "out" ? <Badge size="sm" variant="destructive">No stock</Badge> : null}
                            </span>
                          </TableCell>
                          <TableCell><Clock at={order.nextDoseAt} now={now} problem dangerous={MEDICATION_FLAGS.doseMissed(order, now)} /></TableCell>
                          <TableCell>{order.verifiedById ? staffName(data.staff, order.verifiedById) : <span className="hd-warn">Nobody yet</span>}</TableCell>
                          <TableCell><RowActions transitions={medicationTransitions(order, viewer)} onRun={(t) => onMedicationTransition(order, t)} label={"Actions for " + order.drug} /></TableCell>
                        </TableRow>
                      );
                    })}
                  </TableBody>
                </Table>
              </TableWrap>
              <TableFoot shown={rows.length} total={scoped.length} noun={ward === "all" ? "orders" : "orders on " + wardName(ward)} />
            </>
          )}
        </Band>
      </>
    );
  }

  const STOCK_FILTER = [{ value: "all", label: "All stock states" }].concat(STOCK_STATUS.map((s) => ({ value: s.id, label: s.label })));

  function FormularyScreen({ data, now, viewer, onNavigate, onReorder, onNewLine, onImport, onExport }) {
    const [query, setQuery] = React.useState("");
    const [stock, setStock] = React.useState("all");
    const { sort, onSort } = useSort("name", "asc");

    const low = belowReorder(data.formulary);
    const out = outOfStock(data.formulary);
    const affected = data.orders.filter((o) => {
      const drug = drugById(data.formulary, o.drugId);
      return drug && (drug.stock === "out" || drug.stock === "low") && (o.status === "active" || o.status === "awaiting_verification");
    });

    const dirty = !!query || stock !== "all";
    const clear = () => { setQuery(""); setStock("all"); };
    const filtered = data.formulary.filter((drug) => {
      if (stock !== "all" && drug.stock !== stock) return false;
      if (query && (drug.name + " " + drug.form + " " + drug.supplier).toLowerCase().indexOf(query.toLowerCase()) < 0) return false;
      return true;
    });
    const rows = sortRows(filtered, sort, {
      name: (d) => d.name,
      onHand: (d) => d.onHand,
      expiry: (d) => d.earliestExpiry || Infinity,
    });

    return (
      <>
        <PageHeader
          path="/formulary"
          title="Formulary and stock"
          sub={"What " + HD_HOSPITAL.short + " may prescribe, and how much of it is in the cupboard."}
          actions={
            <>
              <ImportButton viewer={viewer} onImport={onImport} />
              <ExportMenu scope={dirty ? filtered.length + " lines matching the filters" : "All " + data.formulary.length + " formulary lines"}
                onExport={(format) => onExport("Formulary", dirty ? "Filtered formulary" : "Whole formulary", filtered.length, format)} />
              <Button size="sm" onClick={onNewLine}><Icon name="plus" />New formulary line</Button>
            </>
          }
        />
        <Figures three items={[
          { label: "Lines below reorder", value: low.length, qualifier: out.length + " of them at zero" },
          { label: "Courses relying on them", value: affected.length, qualifier: "active or unverified orders for a low or empty line" },
          { label: "Lines in the formulary", value: data.formulary.length, qualifier: data.formulary.filter((d) => d.stock === "discontinued").length + " discontinued and unprescribable" },
        ]} />

        <Band flush>
          <FilterBar query={query} onQuery={setQuery} placeholder="Search drug, form or supplier…" dirty={dirty} onClear={clear}
            selects={[{ id: "stock", label: "Stock", items: STOCK_FILTER, value: stock, onChange: setStock }]} />
          {rows.length === 0 ? <NoResults noun="formulary lines" onClear={clear} /> : (
            <>
              <TableWrap>
                <Table>
                  <TableHeader>
                    <TableRow>
                      <TableHead><SortHead label="Drug" sortKey="name" sort={sort} onSort={onSort} /></TableHead>
                      <TableHead>Route</TableHead>
                      <TableHead>Stock</TableHead>
                      <TableHead style={{ minWidth: "11rem" }}><SortHead label="On hand" sortKey="onHand" sort={sort} onSort={onSort} /></TableHead>
                      <TableHead className="hd-num">Courses</TableHead>
                      <TableHead><SortHead label="Earliest expiry" sortKey="expiry" sort={sort} onSort={onSort} /></TableHead>
                      <TableHead>Supplier</TableHead>
                      <TableHead>Action</TableHead>
                    </TableRow>
                  </TableHeader>
                  <TableBody>
                    {rows.map((drug) => {
                      const courses = ordersForDrug(data.orders, drug.id);
                      const percent = drug.reorderAt ? (drug.onHand / (drug.reorderAt * 3)) * 100 : 0;
                      return (
                        <TableRow key={drug.id}>
                          <TableCell>
                            <span className="hd-person__text">
                              <span className="hd-person__name">{drug.name}{drug.controlled ? " " : ""}{drug.controlled ? <Badge size="sm" variant="outline">Controlled</Badge> : null}</span>
                              <span className="hd-person__meta">{drug.form}</span>
                            </span>
                          </TableCell>
                          <TableCell>{labelOf(DRUG_ROUTES, drug.route)}</TableCell>
                          <TableCell><StatusBadge values={STOCK_STATUS} value={drug.stock} /></TableCell>
                          <TableCell>
                            <span style={{ display: "flex", flexDirection: "column", gap: 4, minWidth: "9rem" }}>
                              <span className="hd-footnote">{formatCount(drug.onHand)} {drug.unit}{drug.reorderAt ? " · reorder at " + formatCount(drug.reorderAt) : ""}</span>
                              <StockBar percent={percent} tone={FORMULARY_FLAGS.belowReorder(drug) ? "warn" : null} />
                            </span>
                          </TableCell>
                          <TableCell className="hd-num">{courses.length}</TableCell>
                          <TableCell>{drug.earliestExpiry ? formatWhen(drug.earliestExpiry, now) : <span className="hd-muted">No batch held</span>}</TableCell>
                          <TableCell>{drug.supplier}</TableCell>
                          <TableCell>
                            {drug.reorderedAt
                              ? <span className="hd-footnote">Ordered {formatWhen(drug.reorderedAt, now)}</span>
                              : FORMULARY_FLAGS.belowReorder(drug)
                                ? <Button size="sm" variant="outline" onClick={() => onReorder(drug)}>Order stock</Button>
                                : <span className="hd-muted">—</span>}
                          </TableCell>
                        </TableRow>
                      );
                    })}
                  </TableBody>
                </Table>
              </TableWrap>
              <TableFoot shown={rows.length} total={data.formulary.length} noun="formulary lines" />
            </>
          )}
        </Band>
      </>
    );
  }

  Object.assign(window, { MedicationScreen, FormularyScreen });
})();
