/* Doctors, employees, and one person's record.
   Two views of one staff array (metrics.js: doctorsOf, employeesOf) — never two
   lists. Doctors is the medical family; Employees is everybody with a badge, so
   somebody new is created once, on Employees, and appears in both.
   Commit model: INSTANT. Access changes apply immediately with an undo toast. */
(() => {
  const {
    Button, Badge, Avatar, Alert, AlertTitle, AlertDescription,
    Table, TableHeader, TableBody, TableRow, TableHead, TableCell,
  } = window.OriginDesignSystem_7c998b;

  const STAFF_STATUS_FILTER = [{ value: "all", label: "All employment states" }].concat(STAFF_STATUS.map((s) => ({ value: s.id, label: s.label })));
  const SPECIALTY_FILTER = [{ value: "all", label: "All specialties" }].concat(SPECIALTIES);
  const FAMILY_FILTER = [{ value: "all", label: "All job families" }].concat(JOB_FAMILIES);

  function DoctorsScreen({ data, now, viewer, onNavigate, onStaffTransition, onExport }) {
    const [query, setQuery] = React.useState("");
    const [specialty, setSpecialty] = React.useState("all");
    const [status, setStatus] = React.useState("all");
    const { sort, onSort } = useSort("name", "asc");

    const doctors = doctorsOf(data.staff);
    const dirty = !!query || specialty !== "all" || status !== "all";
    const clear = () => { setQuery(""); setSpecialty("all"); setStatus("all"); };
    const filtered = doctors.filter((person) => {
      if (specialty !== "all" && person.specialty !== specialty) return false;
      if (status !== "all" && person.status !== status) return false;
      if (query && (person.name + " " + person.jobTitle + " " + (person.gmc || "")).toLowerCase().indexOf(query.toLowerCase()) < 0) return false;
      return true;
    });
    const rows = sortRows(filtered, sort, {
      name: (p) => p.name,
      booked: (p) => interventionsForSurgeon(data.interventions, p.id).length,
      started: (p) => p.startedAt,
    });

    return (
      <>
        <PageHeader
          path="/doctors"
          title="Doctors"
          sub={doctors.length + " of the " + data.staff.length + " people on the badge system are in the medical family. Somebody new is added on Employees."}
          actions={<ExportMenu scope={dirty ? filtered.length + " doctors matching the filters" : "All " + doctors.length + " doctors"}
            onExport={(format) => onExport("Doctors", dirty ? "Filtered doctors" : "All doctors", filtered.length, format)} />}
        />
        <Band flush>
          <FilterBar query={query} onQuery={setQuery} placeholder="Search name, grade or GMC number…" dirty={dirty} onClear={clear}
            selects={[
              { id: "specialty", label: "Specialty", items: SPECIALTY_FILTER, value: specialty, onChange: setSpecialty },
              { id: "status", label: "Employment", items: STAFF_STATUS_FILTER, value: status, onChange: setStatus },
            ]} />
          {rows.length === 0 ? <NoResults noun="doctors" onClear={clear} /> : (
            <>
              <TableWrap>
                <Table>
                  <TableHeader>
                    <TableRow>
                      <TableHead><SortHead label="Doctor" sortKey="name" sort={sort} onSort={onSort} /></TableHead>
                      <TableHead>Specialty</TableHead>
                      <TableHead>Employment</TableHead>
                      <TableHead>Base ward</TableHead>
                      <TableHead className="hd-num"><SortHead label="Procedures" sortKey="booked" sort={sort} onSort={onSort} /></TableHead>
                      <TableHead className="hd-num">Patients as consultant</TableHead>
                      <TableHead>Extension</TableHead>
                      <TableHead>Action</TableHead>
                    </TableRow>
                  </TableHeader>
                  <TableBody>
                    {rows.map((person) => (
                      <TableRow key={person.id}>
                        <TableCell>
                          <PersonCell name={person.name} avatar={person.avatar} meta={person.jobTitle + (person.gmc ? " · " + person.gmc : "")}
                            onOpen={() => onNavigate("/doctors/" + person.id)} />
                        </TableCell>
                        <TableCell>{person.specialty ? labelOf(SPECIALTIES, person.specialty) : <span className="hd-muted">Not recorded</span>}</TableCell>
                        <TableCell>
                          <span className="hd-actions__row">
                            <StatusBadge values={STAFF_STATUS} value={person.status} />
                            {person.status === "on_leave" && person.leaveUntil ? <span className="hd-footnote">until {formatWhen(person.leaveUntil, now)}</span> : null}
                          </span>
                        </TableCell>
                        <TableCell>{person.ward ? wardName(person.ward) : <span className="hd-muted">No base ward</span>}</TableCell>
                        <TableCell className="hd-num">{interventionsForSurgeon(data.interventions, person.id).length}</TableCell>
                        <TableCell className="hd-num">{data.admissions.filter((a) => a.consultantId === person.id).length}</TableCell>
                        <TableCell>{person.phone}</TableCell>
                        <TableCell><RowActions transitions={staffTransitions(person, viewer)} onRun={(t) => onStaffTransition(person, t)} label={"Actions for " + person.name} /></TableCell>
                      </TableRow>
                    ))}
                  </TableBody>
                </Table>
              </TableWrap>
              <TableFoot shown={rows.length} total={doctors.length} noun="doctors" />
            </>
          )}
        </Band>
      </>
    );
  }

  function EmployeesScreen({ data, now, viewer, onNavigate, onStaffTransition, onNewEmployee, onImport, onExport }) {
    const [query, setQuery] = React.useState("");
    const [family, setFamily] = React.useState("all");
    const [status, setStatus] = React.useState("all");
    const { sort, onSort } = useSort("name", "asc");

    const everybody = employeesOf(data.staff);
    const dirty = !!query || family !== "all" || status !== "all";
    const clear = () => { setQuery(""); setFamily("all"); setStatus("all"); };
    const filtered = everybody.filter((person) => {
      if (family !== "all" && person.family !== family) return false;
      if (status !== "all" && person.status !== status) return false;
      if (query && (person.name + " " + person.jobTitle + " " + person.email).toLowerCase().indexOf(query.toLowerCase()) < 0) return false;
      return true;
    });
    const rows = sortRows(filtered, sort, {
      name: (p) => p.name,
      started: (p) => p.startedAt,
      family: (p) => labelOf(JOB_FAMILIES, p.family),
    });
    const suspended = everybody.filter((p) => p.status === "suspended");

    return (
      <>
        <PageHeader
          path="/employees"
          title="Employees"
          sub={everybody.length + " people on the badge system across " + JOB_FAMILIES.length + " job families, including the " + doctorsOf(data.staff).length + " in the medical family."}
          actions={
            <>
              <ImportButton viewer={viewer} onImport={onImport} />
              <ExportMenu scope={dirty ? filtered.length + " employees matching the filters" : "All " + everybody.length + " employees"}
                onExport={(format) => onExport("Employees", dirty ? "Filtered employees" : "All employees", filtered.length, format)} />
              <Button size="sm" onClick={onNewEmployee}><Icon name="plus" />New employee</Button>
            </>
          }
        />
        {suspended.length ? (
          <div className="hd-alertwrap">
            <Alert variant="warning">
              <AlertTitle>{suspended.length === 1 ? "One account is suspended" : suspended.length + " accounts are suspended"}</AlertTitle>
              <AlertDescription>{suspended.map((p) => p.name + " — " + (p.suspendedNote || "no reason recorded")).join(" · ")}</AlertDescription>
            </Alert>
          </div>
        ) : null}
        <Band flush>
          <FilterBar query={query} onQuery={setQuery} placeholder="Search name, job title or email…" dirty={dirty} onClear={clear}
            selects={[
              { id: "family", label: "Job family", items: FAMILY_FILTER, value: family, onChange: setFamily },
              { id: "status", label: "Employment", items: STAFF_STATUS_FILTER, value: status, onChange: setStatus },
            ]} />
          {rows.length === 0 ? <NoResults noun="employees" onClear={clear} /> : (
            <>
              <TableWrap>
                <Table>
                  <TableHeader>
                    <TableRow>
                      <TableHead><SortHead label="Employee" sortKey="name" sort={sort} onSort={onSort} /></TableHead>
                      <TableHead><SortHead label="Job family" sortKey="family" sort={sort} onSort={onSort} /></TableHead>
                      <TableHead>What they may do</TableHead>
                      <TableHead>Employment</TableHead>
                      <TableHead>Base ward</TableHead>
                      <TableHead><SortHead label="Started" sortKey="started" sort={sort} onSort={onSort} /></TableHead>
                      <TableHead>Action</TableHead>
                    </TableRow>
                  </TableHeader>
                  <TableBody>
                    {rows.map((person) => (
                      <TableRow key={person.id}>
                        <TableCell>
                          <PersonCell name={person.name} avatar={person.avatar} meta={person.jobTitle + " · " + person.email}
                            onOpen={() => onNavigate((person.family === "medical" ? "/doctors/" : "/employees/") + person.id)} />
                        </TableCell>
                        <TableCell>{labelOf(JOB_FAMILIES, person.family)}</TableCell>
                        <TableCell>{labelOf(STAFF_ROLES, person.staffRole)}</TableCell>
                        <TableCell><StatusBadge values={STAFF_STATUS} value={person.status} /></TableCell>
                        <TableCell>{person.ward ? wardName(person.ward) : <span className="hd-muted">No base ward</span>}</TableCell>
                        <TableCell>{person.startedAt > now ? "Starts " + formatWhen(person.startedAt, now) : formatWhen(person.startedAt, now)}</TableCell>
                        <TableCell><RowActions transitions={staffTransitions(person, viewer)} onRun={(t) => onStaffTransition(person, t)} label={"Actions for " + person.name} /></TableCell>
                      </TableRow>
                    ))}
                  </TableBody>
                </Table>
              </TableWrap>
              <TableFoot shown={rows.length} total={everybody.length} noun="employees" />
            </>
          )}
        </Band>
      </>
    );
  }

  /* One record for anybody with a badge, reached from either directory. The
     route it renders under decides the breadcrumb, so a doctor opened from
     Doctors reads Doctors / their name. */
  function StaffScreen({ data, now, viewer, staffId, routePath, onNavigate, onStaffTransition, onReactToNote, onExport }) {
    const person = staffById(data.staff, staffId);
    const procedures = interventionsForSurgeon(data.interventions, person.id);
    const upcoming = procedures.filter((i) => i.status === "requested" || i.status === "scheduled" || i.status === "in_theatre");
    const asConsultant = data.admissions.filter((a) => a.consultantId === person.id);
    const openAsConsultant = openAdmissions(asConsultant);
    const written = commentsByAuthor(data.comments, person.id);
    const prescribed = data.orders.filter((o) => o.prescriberId === person.id);
    const verified = data.orders.filter((o) => o.verifiedById === person.id);

    return (
      <>
        <PageHeader path={routePath} params={{ id: person.id }} crumb={person.name} title={person.name}
          actions={<ExportMenu scope={"This record and the " + procedures.length + " procedures against it"} onExport={(format) => onExport("Staff record", person.name + " · " + person.jobTitle, 1, format)} />} />

        <div className="hd-record">
          <div className="hd-record__id">
            <Avatar size={72} src={person.avatar} alt={"Photograph of " + person.name} fallback={initialsOf(person.name)} />
            <div className="hd-record__text">
              <span className="hd-record__name">{person.name}</span>
              <span className="hd-record__meta">
                <span>{person.jobTitle}</span>
                <span>{labelOf(JOB_FAMILIES, person.family)}</span>
                <StatusBadge values={STAFF_STATUS} value={person.status} />
                {person.id === viewer.id ? <Badge size="sm" variant="secondary">This is you</Badge> : null}
              </span>
            </div>
          </div>
          <div className="hd-record__actions">
            <Transitions transitions={staffTransitions(person, viewer)} onRun={(t) => onStaffTransition(person, t)} />
            {person.id === viewer.id ? <Button variant="outline" size="sm" onClick={() => onNavigate("/me/profile")}>Edit your profile</Button> : null}
          </div>
        </div>

        {person.status === "suspended" ? (
          <div className="hd-alertwrap">
            <Alert variant="warning">
              <AlertTitle>Access is suspended</AlertTitle>
              <AlertDescription>{person.suspendedNote || "No reason has been recorded against this suspension."} Nothing in Ward Desk can be signed by this account until access is restored.</AlertDescription>
            </Alert>
          </div>
        ) : null}

        <Figures three items={[
          { label: "Procedures against their name", value: procedures.length, qualifier: upcoming.length + " still to happen" },
          { label: "Patients as consultant", value: asConsultant.length, qualifier: openAsConsultant.length + " of them on a ward now" },
          { label: "Notes written", value: written.length, qualifier: written.length ? "most recently " + formatWhen(written[0].at, now) : "nothing written yet" },
        ]} />

        <Band title="Record">
          <Pairs items={[
            { label: "Email", value: person.email },
            { label: "Extension", value: person.phone },
            { label: "What they may do", value: labelOf(STAFF_ROLES, person.staffRole) },
            { label: "Specialty", value: person.specialty ? labelOf(SPECIALTIES, person.specialty) : "Not applicable" },
            { label: "Base ward", value: person.ward ? wardName(person.ward) : "No base ward" },
            { label: "Started", value: person.startedAt > now ? "Starts " + formatWhen(person.startedAt, now) : formatWhen(person.startedAt, now) },
            { label: "Registration", value: person.gmc || "Not a registered clinician" },
            { label: "Prescribing", value: prescribed.length ? prescribed.length + " orders prescribed" : verified.length ? verified.length + " orders verified" : "No orders against their name" },
          ]} />
        </Band>

        <Band title={"What they are holding (" + (upcoming.length + openAsConsultant.length) + ")"} note="Procedures still to happen and admissions still open — the two things that would need handing over.">
          {upcoming.length + openAsConsultant.length ? (
            <div className="hd-rows">
              {upcoming.map((intervention) => (
                <div className="hd-row" key={intervention.id}>
                  <div className="hd-row__text">
                    <span className="hd-row__title"><button type="button" className="hd-linkbtn" onClick={() => onNavigate("/interventions/" + intervention.id)}>{intervention.name}</button></span>
                    <span className="hd-row__note">{patientName(data.patients, intervention.patientId)} · {intervention.scheduledAt ? formatWhen(intervention.scheduledAt, now) : "not scheduled"}</span>
                  </div>
                  <StatusBadge values={INTERVENTION_STATUS} value={intervention.status} />
                </div>
              ))}
              {openAsConsultant.map((admission) => (
                <div className="hd-row" key={admission.id}>
                  <div className="hd-row__text">
                    <span className="hd-row__title"><button type="button" className="hd-linkbtn" onClick={() => onNavigate("/patients/" + admission.patientId)}>{patientName(data.patients, admission.patientId)}</button></span>
                    <span className="hd-row__note">{admission.bed ? wardName(admission.ward) + " " + admission.bed : wardName(admission.ward) + " — no bed yet"} · {admission.reason}</span>
                  </div>
                  <StatusBadge values={ADMISSION_STATUS} value={admission.status} />
                </div>
              ))}
            </div>
          ) : <p className="hd-footnote">Nothing open against their name — no procedure to do and no admission still on a ward.</p>}
        </Band>

        <Band title={"Notes written (" + written.length + ")"} note="Everything this person has written on a record, most recent first.">
          {written.length ? (
            <div className="hd-notes">
              {written.map((comment) => (
                <Note key={comment.id} comment={comment} staff={data.staff} viewer={viewer} now={now} onReact={onReactToNote}
                  context={recordTitle(data, comment.record.type, comment.record.id)} />
              ))}
            </div>
          ) : <p className="hd-footnote">Nothing written yet.</p>}
        </Band>
      </>
    );
  }

  Object.assign(window, { DoctorsScreen, EmployeesScreen, StaffScreen });
})();
