import ConfirmDialog from "@/components/ui/ConfirmDialog.vue";
import { createApp } from "vue";

interface ConfirmDialogOptions {
  title: string;
  content: string;
}
type ResolveReject = (v?: unknown) => void;

// inspired by https://stackoverflow.com/a/69773076/6071058
/*
 * We need a separate service for the ConfirmDialog, because we don't want the 
 * boilerplate of including the component and the handling of the promises inside
 * of every component where we need a confirm dialog.
 *
 * With this service, one can simply import the dialog and use it, e.g.
 *
import dialog from "@/utils/confirm-dialog";
const someMethodToConfirm = async () => {
  const options = {
    title: 'Dialog Title',
    content: 'Do you really wanna?'
  };
  try {
    await dialog.confirm(options);
    doSomethingWhenConfirmed();
  } catch (e) {
    log.debug("rejected");
    doSomethingWhenRejected()
  }
};

 */
export default {
  confirm(options: ConfirmDialogOptions) {
    const mountEl = document.createElement("div");
    document.body.appendChild(mountEl);

    let _resolve: ResolveReject, _reject: ResolveReject;

    const promise = new Promise((resolve, reject) => {
      _resolve = resolve;
      _reject = reject;
    });

    const cleanUp = () => {
      mountEl?.parentNode?.removeChild(mountEl);
      dialog.unmount();
    };

    const dialog = createApp(ConfirmDialog, {
      isOpen: true,
      title: options.title,
      content: options.content,
      onClose() {
        cleanUp();
        _reject();
      },
      onConfirm() {
        cleanUp();
        _resolve();
      },
    });
    dialog.mount(mountEl);
    return promise;
  },
};
