import _Vue from 'vue';

class EE<Message, Result> {
  name: string;
  callback: ((m?: Message) => Promise<Result>) | null;

  constructor(name: string) {
    this.name = name;
    this.callback = null;
  }

  subscribe(callback: (m?: Message) => Promise<Result>) {
    this.callback = callback;
  }

  emit(value?: Message): Promise<Result> {
    if (this.callback === null) {
      throw new Error('No handler subscribed for event: ' + this.name + '. Have you include the <Alerts> component in your page?');
    } else {
      return this.callback(value);
    }
  }

  off() {
    this.callback = null;
  }
}

export interface ConfirmOption {
  content: string;
}

export interface PromptOption {
  content: string;
  confirmText?: string;
  cancelText?: string;
}

const confirmEE = new EE<ConfirmOption, undefined>('confirm');
const promptEE = new EE<PromptOption, undefined>('prompt');

export const subscribeConfirm = confirmEE.subscribe.bind(confirmEE);

export const subscribePrompt = promptEE.subscribe.bind(promptEE);

export const offConfirm = confirmEE.off.bind(confirmEE);

export const offPrompt = promptEE.off.bind(promptEE);

export const Alerts = {
  install(Vue: typeof _Vue) {
    Vue.prototype.$confirm = confirmEE.emit.bind(confirmEE);
    Vue.prototype.$prompt = promptEE.emit.bind(promptEE);
  },
};
