import { defineNuxtPlugin } from "nuxt/app";
import { h, render } from "vue";
import DialogHost from "../components/dialog/Host.vue";
import DialogDefaultConfirm from "../components/dialog/default/Confirm.vue";
import DialogDefaultNotify from "../components/dialog/default/Notify.vue";
import DialogDefaultLoading from "../components/dialog/default/Loading.vue";
import DialogDefaultPrinting from "../components/dialog/default/Printing.vue";
import DialogDefaultVerifyUser from "../components/dialog/default/VerifyUser.vue";
export default defineNuxtPlugin(async (nuxtApp) => {
  const dialogComponents = {
    confirmDialog: DialogDefaultConfirm,
    notifyDialog: DialogDefaultNotify,
    loadingDialog: DialogDefaultLoading,
    printingDialog: DialogDefaultPrinting,
    verifyUserDialog: DialogDefaultVerifyUser
  };
  let hostOpenFn = null;
  let hostCloseFn = null;
  const setDialogHost = (openFn, closeFn) => {
    hostOpenFn = openFn;
    hostCloseFn = closeFn;
  };
  const setDialogComponents = ((components) => {
    Object.assign(dialogComponents, components);
  });
  const open = (component, props = {}) => {
    return hostOpenFn?.(component, props).promise ?? Promise.reject("No dialog host registered");
  };
  const openPromise = async (component, promiseInput, props = {}) => {
    const dialogInstance = hostOpenFn?.(component, props);
    try {
      if (promiseInput instanceof Promise) {
        return await promiseInput;
      }
      if (Array.isArray(promiseInput)) {
        const promises = promiseInput.map((item) => {
          if (typeof item === "function") {
            try {
              return Promise.resolve(item());
            } catch (err) {
              return Promise.reject(err);
            }
          } else {
            return Promise.resolve(item);
          }
        });
        return await Promise.all(promises);
      }
      try {
        return await Promise.resolve(promiseInput());
      } catch (err) {
        return Promise.reject(err);
      }
    } finally {
      dialogInstance?.closeInstance();
    }
  };
  const confirm = (props = {}) => open(dialogComponents.confirmDialog, props);
  const notify = (props = {}) => open(dialogComponents.notifyDialog, props);
  const verifyUser = (props = {}) => open(dialogComponents.verifyUserDialog, props);
  const loading = async (promiseInput, props = {}) => openPromise(dialogComponents.loadingDialog, promiseInput, props);
  const printing = async (promiseInput, props = {}) => openPromise(dialogComponents.printingDialog, promiseInput, props);
  nuxtApp.hook("app:mounted", () => {
    const el = document.createElement("div");
    el.id = "__nuxt_dialog_host";
    document.body.appendChild(el);
    const vnode = h(DialogHost);
    vnode.appContext = nuxtApp.vueApp._context;
    render(vnode, el);
  });
  nuxtApp.provide("dialog", { open, confirm, notify, verifyUser, loading, printing, setDialogHost, setDialogComponents });
});
