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>
  );
}
