import { App, createApp, defineComponent, h, inject, nextTick, ref } from 'vue';
import BmsModal from '../../components/layout/BmsModal.vue';
import { InjectionKey } from 'vue';
import { NotificationInstance } from '@/plugins/notifications/notification.model';

const createConfirmComponent = (
  modalOptions: { question: string; title: string },
  resolve: Function,
  reject: Function,
) => {
  return defineComponent({
    props: {
      question: {
        type: String,
      },
      title: {
        type: String,
      },
    },
    components: { BmsModal },
    setup() {
      const isActive = ref<boolean>(true);
      const confirm = () => {
        close();
        return resolve();
      };
      const discard = () => {
        close();
        return reject();
      };
      const close = () => {
        isActive.value = false;
      };

      return {
        question: modalOptions.question,
        title: modalOptions.title,
        isActive,
        confirm,
        discard,
      };
    },
    render() {
      return h(
        //@ts-ignore
        BmsModal,
        {
          title: this.title,
          modelValue: this.isActive,
          submitAction: this.confirm,
          cancelAction: this.discard,
          submitLabel: 'Confirmer',
          onClose: this.discard,
        },
        { default: () => h('p', this.question) },
      );
    },
  });
};
export const ConfirmInstance = Symbol() as InjectionKey<NotificationInstance>;

export const confirmPlugin = {
  install(app: App) {
    app.provide(
      '$confirm',
      async (question: string, title?: string): Promise<boolean> => {
        let confirmApp: App | undefined;
        return new Promise(async (higherResolve, higherReject) => {
          try {
            await new Promise(async (resolve, reject) => {
              const component = createConfirmComponent(
                { question, title: title || 'Confirmer' },
                resolve,
                reject,
              );
              await nextTick();
              confirmApp = createApp(component);
              confirmApp.mount('#confirm');
            });
            higherResolve(true);
          } catch (e) {
            higherResolve(false);
          } finally {
            if (confirmApp) {
              confirmApp.unmount();
            }
          }
        });
      },
    );
    const confirm = {
      render() {
        return h('div', { id: 'confirm' });
      },
    };
    app.component('BmsConfirm', confirm);
    app.component('bms-confirm', confirm);
  },
};

export function useConfirm() {
  const confirm = inject(
    '$confirm',
    (question: string, title?: string): Promise<boolean> => {
      return Promise.resolve(true);
    },
  );
  return {
    confirm,
  };
}
