import type { MouseEvent } from "react";
import { Fragment } from "react";
import type { ContextRecord } from "../../api/types";
import { formatDate } from "../../flow";
import { whenLabel } from "../../logic/format";
import { recordPill } from "../../logic/pills";
import { recordTypes } from "../../logic/records";
import { Button, Callout, cn, type IconName, linkButtonClass, Tag, tbl } from "../kit";
import { Pill } from "../Pill";
import { RowMenu, type MenuItem } from "../RowMenu";
export const originLabel: Record<ContextRecord["origin"], string> = {
upload: "Uploaded",
pasted: "Pasted note",
camera: "Photo",
app: "From MARMAR Health",
check_in: "From a check-in call",
};
const originIcon: Record<ContextRecord["origin"], IconName> = {
upload: "upload-2-line",
pasted: "file-text-line",
camera: "upload-2-line",
app: "heart-pulse-line",
check_in: "chat-voice-line",
};
export type RecordActions = {
open: (r: ContextRecord) => void;
edit: (r: ContextRecord) => void;
remove: (r: ContextRecord) => void;
confirm: (r: ContextRecord) => void;
readAgain: (r: ContextRecord) => void;
};
const canEdit = (r: ContextRecord) => r.origin !== "app" && r.origin !== "check_in";
// What MARMAR Health shares stays the patient's; everything added in Context can be removed (REC-1).
const canRemove = (r: ContextRecord) => r.origin !== "app";
const canReadAgain = (r: ContextRecord) => r.reading === "failed" && r.contentType !== "text/plain" && r.origin !== "check_in";
/** REC-4: one row per record with where it came from, when it was added and its reading state. */
export function RecordsTable({ records, patientFirstName, actions }: { records: ContextRecord[]; patientFirstName: string; actions: RecordActions }) {
const click = (e: MouseEvent, r: ContextRecord) => {
if ((e.target as HTMLElement).closest("a, button, [role=menu]")) return;
actions.open(r);
};
return (
<div className="min-w-0">
<table className={tbl.table}>
<thead className={tbl.head}>
<tr>
<th scope="col" className={tbl.th}>Record</th>
<th scope="col" className={tbl.th}>Source</th>
<th scope="col" className={tbl.th}>Date on it</th>
<th scope="col" className={tbl.th}>Added</th>
<th scope="col" className={tbl.th}>State</th>
<th scope="col" className={tbl.th}>
<span className="sr-only">Actions</span>
</th>
</tr>
</thead>
<tbody className={tbl.body}>
{records.map((r) => {
const items: MenuItem[] = [
{ label: "Read its lines", icon: "eye-line", onSelect: () => actions.open(r) },
...(canEdit(r) ? [{ label: "Edit details", icon: "edit-line" as const, onSelect: () => actions.edit(r) }] : []),
...(canReadAgain(r) ? [{ label: "Read it again", icon: "refresh-line" as const, onSelect: () => actions.readAgain(r) }] : []),
...(canRemove(r) ? [{ label: "Remove", icon: "delete-bin-line" as const, danger: true, onSelect: () => actions.remove(r) }] : []),
];
const flagged = !!r.heldBack || !!r.readingError;
// A flagged record's detail row carries the line under it.
const cell = flagged ? cn(tbl.td, "shadow-none") : tbl.td;
return (
<Fragment key={r.id}>
<tr className={cn(tbl.row, tbl.clickable, flagged && "@max-[640px]/pd:shadow-none")} onClick={(e) => click(e, r)}>
<td className={flagged ? cn(tbl.lead, "shadow-none") : tbl.lead}>
<button type="button" className={tbl.name} onClick={() => actions.open(r)}>
{r.title}
</button>
<small className={tbl.sub}>{recordTypes[r.type]}</small>
</td>
<td data-label="Source" className={cell}>
<span className="inline-flex flex-col items-start gap-1 @max-[640px]/pd:items-end">
<Tag lead={originIcon[r.origin]}>{originLabel[r.origin]}</Tag>
{r.place && <small className={tbl.sub}>{r.place}</small>}
</span>
</td>
<td data-label="Date on it" className={cn(cell, "whitespace-nowrap tabular-nums")}>
{r.recordDate ? formatDate(r.recordDate) : <span className="text-subtle">Not given</span>}
</td>
<td data-label="Added" className={cell}>
<span>
<span className="whitespace-nowrap tabular-nums">{whenLabel(r.addedAt)}</span>
<small className={tbl.sub}>by {r.addedBy}</small>
</span>
</td>
<td data-label="State" className={cell}>
<Pill pill={recordPill(r)} />
</td>
<td className={flagged ? cn(tbl.menu, "shadow-none") : tbl.menu}>
<RowMenu label={`More for ${r.title}`} items={items} />
</td>
</tr>
{flagged && (
<tr className="@max-[640px]/pd:block @max-[640px]/pd:shadow-[inset_0_-1px_0_var(--color-hairline)]">
<td colSpan={6} className="px-2 pb-3 shadow-[inset_0_-1px_0_var(--color-hairline)] @max-[640px]/pd:block @max-[640px]/pd:px-0 @max-[640px]/pd:shadow-none">
<div className="flex flex-col gap-2">
{r.readingError && (
<p className="m-0 flex flex-wrap items-center gap-x-3 gap-y-1 text-[13px] text-red-text">
<span>{r.readingError}</span>
{canReadAgain(r) && (
<button type="button" className={linkButtonClass} onClick={() => actions.readAgain(r)}>
Read it again
</button>
)}
</p>
)}
{r.heldBack && (
<Callout
tone="amber"
action={
<>
<Button size="sm" variant="quiet" onClick={() => actions.confirm(r)}>
It is {patientFirstName}'s
</Button>
<Button size="sm" variant="danger" onClick={() => actions.remove(r)}>
Remove it
</Button>
</>
}
>
{r.heldBack.reason} It is not used until you decide.
</Callout>
)}
</div>
</td>
</tr>
)}
</Fragment>
);
})}
</tbody>
</table>
</div>
);
}