import React, { useEffect, useState, useRef } from "react";
import ReactDOM from "react-dom";
import { Modal, ModalProps } from "./ModalMain";
import { Button } from "../button";
import { ModalMessage } from "./ModalMessage";
import { Omit } from "../_type";
import { callBoth } from "../_util/call-both";
import { useTranslation } from "../i18n";
import { mergeRefs } from "../_util/merge-refs";
import { ConfigProvider } from "../configprovider";
import { noop } from "../_util/noop";

/**
 * API 的方式唤起一个告警对话框
 * @param options
 */
export function alert(options: AlertOptions) {
  const { onExited = noop, ...restOptions } = options;
  return new Promise<void>(resolve => {
    const el = document.createElement("div");
    ReactDOM.render(
      <ConfigProvider>
        <ModalAlertAPI
          {...restOptions}
          onButtonClick={() => resolve()}
          onExited={() => {
            onExited();
            ReactDOM.unmountComponentAtNode(el);
          }}
        />
      </ConfigProvider>,
      el
    );
  });
}

export interface TypedAlertOptions extends Omit<AlertOptions, "type"> {}

/**
 * API 的方式唤起一个对话框显示成功信息
 */
export function success(options: TypedAlertOptions) {
  return alert({ type: "success", ...options });
}

/**
 * API 的方式唤起一个对话框显示失败信息
 */
export function error(options: TypedAlertOptions) {
  return alert({ type: "error", ...options });
}

/**
 *  `Modal.success`、`Modal.error` 及 `Modal.alert` 方法接收以下参数：
 */
export interface AlertOptions
  extends Pick<ModalProps, "size" | "onClose" | "onExited" | "popupContainer" | "disableCloseIcon" | "disableEscape"> {
  /**
   * 提示类型
   */
  type?: "error" | "warning" | "success" | "pending" | "infoblue";

  /**
   * 要提示的消息
   */
  message: React.ReactNode;

  /**
   * 可选的详细解释
   */
  description?: React.ReactNode;

  /**
   * 默认告警对话框有唯一的关闭按钮
   *
   * 此处配置按钮的文案
   */
  buttonText?: React.ReactNode;

  /**
   * 如果对话框需要多个按钮，或者需要给按钮绑定事件，可直接传入按钮数组
   *
   * 此配置会覆盖 `buttonText` 的配置
   */
  buttons?: React.ReactElement[];

  /**
   * 是启用点击遮罩关闭
   * @default true
   */
  maskClosable?: boolean;
}

function ModalAlertAPI({
  onButtonClick,
  onClose = noop,
  ...modalProps
}: ModalAlertProps) {
  const [visible, setVisible] = useState(false);

  // 渲染之后，马上显示
  useEffect(() => setVisible(true), []);

  const close = () => {
    onClose();
    setVisible(false);
    onButtonClick();
  };

  return (
    <ModalAlert
      visible={visible}
      onButtonClick={close}
      onClose={close}
      {...modalProps}
    />
  );
}

export interface ModalAlertProps extends AlertOptions, ModalProps {
  onButtonClick(): void;
}

/**
 * 提供原始的 ModalAlert 组件。
 * 推荐使用 `Modal.success()` / `Modal.error()` API 来简化用法
 */
export function ModalAlert({
  type,
  message,
  description,
  ...modalProps
}: ModalAlertProps) {
  useEffect(() => {
    window.focus();
  }, []);
  return (
    <Modal maskClosable {...modalProps}>
      <Modal.Body>
        <ModalMessage icon={type} message={message} description={description} />
      </Modal.Body>
      <Modal.Footer>
        <ModalButton {...modalProps} />
      </Modal.Footer>
    </Modal>
  );
}

function ModalButton({
  buttons,
  buttonText,
  onButtonClick,
}: Partial<ModalAlertProps>) {
  const t = useTranslation();
  const mainButtonRef = useRef<HTMLButtonElement>(null);
  useEffect(() => {
    if (mainButtonRef.current) {
      mainButtonRef.current.focus();
    }
  }, []);

  const okText = buttonText ?? t.okText;

  return (
    <>
      {(
        buttons || [
          <Button type="primary" htmlType="button">
            {okText}
          </Button>,
        ]
      ).map((button, index) => {
        return React.cloneElement(button, {
          key: index,
          onClick: callBoth(button.props.onClick, onButtonClick),
          ref:
            index === 0
              ? mergeRefs(button.props.ref, mainButtonRef)
              : button.props.ref,
        });
      })}
    </>
  );
}
