import React from "react";
import { Modal as ModalMain, ModalProps } from "./ModalMain";
import {
  confirm,
  ModalConfirm,
  ModalConfirmProps,
  ConfirmOptions,
} from "./ModalConfirm";
import {
  success,
  error,
  alert,
  ModalAlert,
  ModalAlertProps,
  AlertOptions,
} from "./ModalAlert";
import { show } from "./ModalShow";
import { forwardRefWithStatics } from "../_util/forward-ref-with-statics";
import { modalEventEmitter } from "./event";
import { noop } from "../_util/noop";

export {
  ModalProps,
  ModalConfirm,
  ModalConfirmProps,
  ConfirmOptions,
  ModalAlert,
  ModalAlertProps,
  AlertOptions,
};

export const Modal = forwardRefWithStatics(
  (props: ModalProps, ref: React.Ref<HTMLDivElement>) => (
    <ModalMain ref={ref} {...props} />
  ),
  {
    /**
     * 渲染对话框的主要内容
     */
    Body: ModalMain.Body,

    /**
     * 渲染对话框的底部内容
     */
    Footer: ModalMain.Footer,

    /**
     * 对话框消息内容，可置于 ModalMain..Body 中
     */
    Message: ModalMain.Message,

    /**
     * 全局配置
     */
    config: ModalMain.config,

    /**
     * API 的方式唤起一个确认对话框
     * @returns 异步返回布尔值，为 `true` 则表示用户确认，为 `false` 则表示用户取消
     */
    confirm,

    /**
     * API 的方式唤起一个对话框显示成功信息
     */
    success,

    /**
     * API 的方式唤起一个对话框显示失败信息
     */
    error,

    /**
     * API 的方式唤起一个对话框显示提醒信息
     */
    alert,

    /**
     * API 的方式唤起一个对话框
     */
    show,

    /**
     * 全局对话框开启回调
     */
    onOpen: (listener = noop) => {
      modalEventEmitter.on("open", listener);
    },

    /**
     * 全局对话框关闭回调
     */
    onClose: (listener = noop) => {
      modalEventEmitter.on("close", listener);
    },
  }
);

Modal.displayName = "Modal";

/**
 * API 方式唤起
 */
export interface ModalStaticAPI {
  /**
   * API 的方式唤起一个确认对话框
   * @param options
   * @returns 异步返回布尔值，为 true 则表示用户确认，为 false 则表示用户取消
   */
  confirm: typeof confirm;

  /**
   * API 的方式唤起一个对话框显示成功信息
   */
  success: typeof success;

  /**
   * API 的方式唤起一个对话框显示失败信息
   */
  error: typeof error;

  /**
   * API 的方式唤起一个告警对话框
   * @param options
   * @returns 异步返回布尔值，为 true 则表示用户确认，为 false 则表示用户取消
   */
  alert: typeof alert;

  /**
   * API 的方式唤起一个对话框
   *
   * 对于部分极端场景，没有可用于渲染对话框的文档流的情况下，可以采取 API 打开对话框。**但是这个功能开发者应该慎用，因为使用 API 打开对话框，实际上会断掉数据流，并不是一个好的实践。**
   */
  show: typeof show;

  /**
   * 对话框全局配置
   */
  config: typeof Modal.config;

  /**
   * 对话框打开回调
   */
  onOpen: (listener: () => void) => void;

  /**
   * 对话框关闭回调
   */
  onClose: (listener: () => void) => void;
}
