import {
  Button,
  Dialog,
  DialogActions,
  DialogContent,
  DialogContentText,
  DialogTitle,
} from "@mui/material";
import React, { type PropsWithChildren } from "react";

type ConfirmContext = (
  message: string | React.ReactElement,
  title?: string,
  confirmButton?: string
) => Promise<boolean>;

const ConfirmContextK = React.createContext<ConfirmContext | null>(null);

export function ConfirmDialogProvider(
  p: PropsWithChildren
): React.ReactElement {
  const [open, setOpen] = React.useState(false);

  const [title, setTitle] = React.useState<string | undefined>(undefined);
  const [message, setMessage] = React.useState<string | React.ReactElement>("");
  const [confirmButton, setConfirmButton] = React.useState<string | undefined>(
    undefined
  );

  const cb = React.useRef<null | ((a: boolean) => void)>(null);

  const handleClose = (confirm: boolean) => {
    setOpen(false);

    if (cb.current !== null) cb.current(confirm);
    cb.current = null;
  };

  const hook: ConfirmContext = (message, title, confirmButton) => {
    setTitle(title);
    setMessage(message);
    setConfirmButton(confirmButton);
    setOpen(true);

    return new Promise((res) => {
      cb.current = res;
    });
  };

  const keyUp = (e: React.KeyboardEvent) => {
    if (e.code === "Enter") handleClose(true);
  };

  return (
    <>
      <ConfirmContextK value={hook}>{p.children}</ConfirmContextK>

      <Dialog
        open={open}
        onClose={() => {
          handleClose(false);
        }}
        aria-labelledby="alert-dialog-title"
        aria-describedby="alert-dialog-description"
        onKeyUp={keyUp}
      >
        {title && <DialogTitle id="alert-dialog-title">{title}</DialogTitle>}
        <DialogContent>
          <DialogContentText id="alert-dialog-description">
            {message}
          </DialogContentText>
        </DialogContent>
        <DialogActions>
          <Button
            onClick={() => {
              handleClose(false);
            }}
            autoFocus
          >
            Cancel
          </Button>
          <Button
            onClick={() => {
              handleClose(true);
            }}
            color="error"
          >
            {confirmButton ?? "Confirm"}
          </Button>
        </DialogActions>
      </Dialog>
    </>
  );
}

export function useConfirm(): ConfirmContext {
  return React.use(ConfirmContextK)!;
}
