import { ConfigProvider, message as oriMessage } from 'antd';
import {
  ArgsProps,
  ConfigOnClose,
  ConfigOptions,
  MessageApi,
} from 'antd/lib/message';
import { Icon } from '../Icon';
import React from 'react';
import './index.less';
import classNames from 'classnames';
import { getUuid } from '@btri-ui/utils';

type Props = {
  type: string;
};
const IconComponent = (props: Props) => {
  const { getPrefixCls } = React.useContext(ConfigProvider.ConfigContext);
  const prefixCls = getPrefixCls('btri-message-icon');
  const { type } = props;
  const iconNames = {
    info: 'AttentionRectangle',
    success: 'CheckOnSquare',
    warning: 'Caution',
    error: 'ErrorDiamond',
    normal: '',
    loading: 'Loading',
    close: 'CloseSmall',
  };

  return iconNames[type] ? (
    <Icon
      spin={type === 'loading'}
      iconName={iconNames[type]}
      className={classNames(`${prefixCls}-box`, `${prefixCls}-${type}`)}
      style={{ marginRight: '8px' }}
    />
  ) : (
    <></>
  );
};
type ExtraProps = {
  closeIcon?: React.ReactNode;
};
type ConfigContent = React.ReactNode;
type ConfigDuration = number | (() => void);
type JointContent = ConfigContent | (ArgsProps & ExtraProps);

let message: MessageApi & {
  normal: (
    content: JointContent,
    duration?: ConfigDuration,
    onClose?: ConfigOnClose,
  ) => any;
} = { ...oriMessage, normal: () => {} };

message.config({ prefixCls: `btri-message ant-message` });
const config = (props: ConfigOptions) => {
  const { prefixCls } = props;
  oriMessage.config({
    ...props,
    prefixCls: `btri-message ${prefixCls}`,
  });
};

const getMsgFn = (type: string) => {
  let showMethodType = type;
  if (type === 'normal') {
    showMethodType = 'info';
  }
  return (
    content: JointContent,
    duration?: ConfigDuration,
    onClose?: ConfigOnClose,
  ) => {
    if (typeof content === 'object') {
      const newContent = content as ArgsProps & ExtraProps;
      const key = newContent.key || getUuid();
      return oriMessage[showMethodType]?.({
        icon: <IconComponent type={type} />,
        onClose,
        duration,
        ...content,
        content: (
          <div className="msg-content">
            {newContent.content}
            {newContent.closeIcon && (
              <div
                className="close-icon"
                onClick={() => {
                  oriMessage.destroy(key);
                }}
              >
                {newContent.closeIcon}
              </div>
            )}
          </div>
        ),
        key,
      });
    } else {
      return oriMessage[showMethodType]?.({
        icon: <IconComponent type={type} />,
        content,
        onClose,
        duration,
      });
    }
  };
};

message = {
  ...oriMessage,
  info: getMsgFn('info'),
  success: getMsgFn('success'),
  warning: getMsgFn('warning'),
  error: getMsgFn('error'),
  normal: getMsgFn('normal'),
  loading: getMsgFn('loading'),
  config,
};

export { message };
