import {
  Button as AntBtn,
  ButtonProps,
  ConfigProvider,
  Modal,
  ModalFuncProps,
} from 'antd';
import React, { useContext, useMemo } from 'react';
import { AOP } from '../utils/AOP';
import './index.less';
import classNames from 'classnames';
import { Icon } from '../Icon';

interface ExtraProps {
  textColor?: string;
  confirmConfig?: ModalFuncProps;
  type?:
    | 'text'
    | 'link'
    | 'ghost'
    | 'default'
    | 'primary'
    | 'dashed'
    | 'secondary'
    | 'danger'
    | 'alarm'
    | 'success'
    | 'errorLink'
    | 'alarmLink'
    | 'successLink';
  afterIcon?: React.ReactNode;
}

const Button: React.FC<Omit<ButtonProps, 'type'> & ExtraProps> = props => {
  // 为了与 antd 的生态保持兼容性，我们要求必须要使用 `.@{ant-prefix}` 变量来生成类名
  const { getPrefixCls } = useContext(ConfigProvider.ConfigContext);
  const prefixCls = getPrefixCls('btri-btn');

  const { confirmConfig, type, textColor, afterIcon, ...res } = props;

  // AOP实例化
  const clickAop = new AOP<React.MouseEvent<HTMLElement, MouseEvent>, void>(
    // loading状态下阻止点击事件
   !props.loading && props.onClick,
  );

  // 开启确认对话框
  const openComfirmModal = () => {
    if (confirmConfig) {
      Modal.confirm(confirmConfig);
    }
  };

  // loading
  const Loading = props.loading ? (
    <Icon iconName="Loading" spin={true}></Icon>
  ) : (
    ''
  );

  // 通过AOP构造函数执行流程
  const onClick = clickAop.before(openComfirmModal).getFunction();

  const newType = useMemo(() => {
    const links = ['errorLink', 'alarmLink', 'successLink'];
    const res = links.findIndex(item => item === type) > -1 ? 'link' : type;
    return res;
  }, [type]);

  return (
    <AntBtn
      icon={Loading}
      {...res}
      className={classNames(
        `${prefixCls}-box`,
        `${prefixCls}-${type}`,
        props.disabled && `${prefixCls}-disabled`,
        !props.children && `${prefixCls}-only-icon`,
        props.loading && `${prefixCls}-loading`,
        props.className,
      )}
      onClick={onClick}
      loading={false}
      type={newType as any}
      style={{ color: textColor, ...props.style }}
    >
      {props.children}
      {afterIcon}
    </AntBtn>
  );
};
export { Button };
