import type { ReactNode } from "react";
import type { CheckIn, CheckInNote } from "../../api/types";
import { isEnded, sentenceNotes } from "../../logic/checkin-events";
import { callOffset, clock, dayLabel, noteKinds, whenLabel } from "../../logic/format";
import { checkInPill } from "../../logic/pills";
import { checkClass, cn, Icon, linkButtonClass } from "../kit";
import { Pill } from "../Pill";
import { NoteIcon } from "./NoteIcon";

const refClass =
  "ml-0.5 inline-flex h-[18px] min-w-[18px] items-center justify-center rounded-full bg-page px-1 align-[1px] font-mono text-[10.5px] leading-none text-cell no-underline shadow-[inset_0_0_0_1px_var(--color-line)] outline-none hover:text-ink hover:shadow-[inset_0_0_0_1px_var(--color-subtle)] focus-visible:shadow-[0_0_0_2px_var(--color-brand)]";

/** Every state the call went through, in order, with its time. */
export function StatusTrail({ call }: { call: CheckIn }) {
  return (
    <ol aria-label="Status" className="m-0 flex list-none flex-wrap items-center gap-x-2 gap-y-2 p-0">
      {call.history.map((h, i) => (
        <li key={i} className="inline-flex items-center gap-1.5">
          {i > 0 && <Icon name="arrow-right-s-line" size={14} className="text-line" />}
          <Pill pill={checkInPill(h.status)} size="sm" />
          <small className="font-mono text-[11.5px] text-subtle">
            {dayLabel(h.at) === "Today" ? clock(h.at) : whenLabel(h.at)}
            {h.detail ? ` · ${h.detail.replace(/_/g, " ")}` : ""}
          </small>
        </li>
      ))}
    </ol>
  );
}

/** Loud only when a patient needs someone now: red, its words, and what to do next. */
export function UrgentBox({ title, children, actions, role = "alert" }: { title: ReactNode; children?: ReactNode; actions?: ReactNode; role?: "alert" | "status" }) {
  return (
    <div role={role} className="flex flex-wrap items-start gap-x-3.5 gap-y-3 rounded-[14px] bg-red-fill px-4 py-3.5">
      <Icon name="alarm-warning-fill" size={22} className="text-red-icon" />
      <div className="flex min-w-0 flex-1 basis-60 flex-col gap-1">
        <strong className="text-[14.5px] leading-5 font-semibold text-[#8f1d14]">{title}</strong>
        {children && <div className="flex flex-col gap-1 text-[13.5px] leading-[19px] text-[#a42418]">{children}</div>}
      </div>
      {actions && <div className="flex flex-wrap items-center gap-2">{actions}</div>}
    </div>
  );
}

/** The notes as they arrive: what was said, in the patient's words, linked to the line in the call text. */
export function NotesList({
  call,
  first,
  picked,
  onPick,
  onJump,
}: {
  call: CheckIn;
  first: string;
  picked: string[];
  onPick: (id: string, on: boolean) => void;
  onJump: (lineIds: string[]) => void;
}) {
  const at = (n: CheckInNote) => {
    const line = call.transcript.find((l) => l.id === n.transcriptLineIds[0]);
    return line ? `${callOffset(line.offsetSeconds)} in the call` : "In the call";
  };
  return (
    <ol className="m-0 flex list-none flex-col p-0" aria-live="polite" aria-label="Notes">
      {call.notes.map((n, i) => (
        <li
          key={n.id}
          id={`note-${n.id}`}
          className={cn("flex scroll-mt-24 items-start gap-3 py-3 shadow-[inset_0_-1px_0_var(--color-hairline)] last:shadow-none", n.urgent && "-mx-2 rounded-lg bg-red-fill/50 px-2 shadow-none")}
        >
          {isEnded(call.status) && !n.urgent && (
            <input
              type="checkbox"
              className={cn(checkClass, "mt-1.5")}
              aria-label={`Choose "${n.text}" to add to the check`}
              checked={picked.includes(n.id) || !!n.addedToCheckAt}
              disabled={!!n.addedToCheckAt}
              onChange={(e) => onPick(n.id, e.target.checked)}
            />
          )}
          <NoteIcon kind={n.kind} />
          <div className="flex min-w-0 flex-1 flex-col gap-1">
            <b className="text-[14px] leading-5 font-medium text-ink">{n.text}</b>
            <q className="text-[13.5px] leading-5 text-cell">{n.quote}</q>
            <small className="flex flex-wrap items-center gap-x-1.5 gap-y-0.5 text-[12px] leading-[18px] text-muted">
              <span className="font-mono text-subtle">{i + 1}</span>
              <span aria-hidden="true">·</span>
              <span>{noteKinds[n.kind]}</span>
              <span aria-hidden="true">·</span>
              <button className={cn(linkButtonClass, "text-[12px] font-normal text-cell")} onClick={() => onJump(n.transcriptLineIds)}>
                {at(n)}
              </button>
              {n.addedToCheckAt && <span className="text-green-text">· added to the check</span>}
              {n.disputed && <span className="text-amber-text">· {first} said "This isn't what I said"</span>}
            </small>
          </div>
          <small className="pt-1 text-[12px] text-subtle">{first}</small>
        </li>
      ))}
      {!call.notes.length && !isEnded(call.status) && <li className="py-6 text-center text-[13.5px] text-muted">Notes appear here as {first} answers.</li>}
    </ol>
  );
}

/** The summary, built only from the notes: each sentence carries the numbers of its notes. */
export function SummaryCard({ call, doctor, noteNumber }: { call: CheckIn; doctor: string; noteNumber: (id: string) => number }) {
  if (!call.summary) return null;
  return (
    <div className="flex flex-col gap-2 rounded-xl bg-tile p-4">
      <b className="text-[14px] leading-5 font-semibold text-ink">Summary for {doctor}</b>
      <p className="m-0 text-[14px] leading-[22px] text-body">
        {call.summary.sentences.map((s, i) => (
          <span key={i}>
            {s.text}
            {sentenceNotes(call, s.noteIds).map((n) => (
              <a key={n.id} className={refClass} href={`#note-${n.id}`} aria-label={`Note ${noteNumber(n.id)}: ${n.text}`}>
                {noteNumber(n.id)}
              </a>
            ))}{" "}
          </span>
        ))}
      </p>
      <small className="text-[12px] text-muted">Built only from the notes. Each sentence links to its notes.</small>
    </div>
  );
}

/** The call text, the source of every note: kept 12 months as text, never as audio. */
export function CallText({ call, first, lit, noteNumber }: { call: CheckIn; first: string; lit: string | null; noteNumber: (id: string) => number }) {
  return (
    <section
      aria-label="Call text"
      className="flex min-w-0 flex-col gap-3 rounded-2xl bg-page p-5 shadow-card max-sm:p-4 @min-[1100px]/pd:sticky @min-[1100px]/pd:top-[72px] @min-[1100px]/pd:max-h-[calc(100dvh-96px)] @min-[1100px]/pd:overflow-y-auto"
    >
      <div className="flex flex-wrap items-baseline justify-between gap-x-3 gap-y-1">
        <h2 className="m-0 text-[15px] leading-5 font-semibold tracking-[-0.01em] text-ink">Call text</h2>
        <span className="font-mono text-[11.5px] text-muted">Kept 12 months · no audio is stored</span>
      </div>
      {call.transcript.length ? (
        <ol className="m-0 flex list-none flex-col gap-0.5 p-0">
          {call.transcript.map((l) => {
            const linked = call.notes.filter((n) => n.transcriptLineIds.includes(l.id));
            return (
              <li
                key={l.id}
                id={`line-${call.id}-${l.id}`}
                className={cn("grid scroll-mt-24 grid-cols-[44px_minmax(0,1fr)] gap-x-2 rounded-lg px-2 py-1.5 transition-colors duration-300", lit === l.id && "bg-amber-fill")}
              >
                <span className="pt-px font-mono text-[11.5px] text-subtle tabular-nums">{callOffset(l.offsetSeconds)}</span>
                <span className="flex min-w-0 flex-col">
                  <span className={cn("text-[12px] leading-[18px] font-medium", l.speaker === "yasmar" ? "text-action" : "text-purple-text")}>{l.speaker === "yasmar" ? "Yasmar" : first}</span>
                  <span className="text-[13.5px] leading-5 text-body">
                    {l.text}
                    {linked.map((n) => (
                      <a key={n.id} className={refClass} href={`#note-${n.id}`} aria-label={`Note ${noteNumber(n.id)}`}>
                        {noteNumber(n.id)}
                      </a>
                    ))}
                  </span>
                </span>
              </li>
            );
          })}
        </ol>
      ) : (
        <p className="m-0 text-[13px] text-muted">The call text appears once {first} accepts.</p>
      )}
    </section>
  );
}
