import { ApiError } from "../../api/client";
import type { SupportCode } from "../../api/types";
import { ConfirmDialog } from "../../components/ui/ConfirmDialog";
import { useToast } from "../../components/ui/toast-context";
import { useCancelCode } from "./hooks";

interface CancelCodeDialogProps {
  /** The code to cancel, or null when the dialog is closed. */
  code: SupportCode | null;
  onClose: () => void;
}

/**
 * Confirm + cancel a support code. Cancelling is consequential: a code cannot
 * be un-cancelled, and if it has not been redeemed yet the end user can no
 * longer use it. We confirm first, then invalidate the list so the row drops.
 */
export function CancelCodeDialog({ code, onClose }: CancelCodeDialogProps) {
  const toast = useToast();
  const cancel = useCancelCode();
  const open = code != null;

  function onConfirm() {
    if (!code) return;
    cancel.mutate(code.code, {
      onSuccess: () => {
        toast.success("Code cancelled", `${code.code} can no longer be used.`);
        onClose();
      },
      onError: (err) => {
        toast.error(
          "Could not cancel code",
          err instanceof ApiError ? err.message : "The relay did not respond.",
        );
      },
    });
  }

  return (
    <ConfirmDialog
      open={open}
      title="Cancel this code?"
      danger
      busy={cancel.isPending}
      confirmLabel="Cancel code"
      cancelLabel="Keep it"
      onConfirm={onConfirm}
      onCancel={onClose}
      body={
        code ? (
          <p>
            This permanently revokes <strong className="mono">{code.code}</strong>.{" "}
            {code.status === "connected"
              ? "An attended session is bound to it; cancelling ends that connection."
              : "The end user will not be able to redeem it. This cannot be undone."}
          </p>
        ) : null
      }
    />
  );
}
