import * as React from 'react';
import {
  ConfigProvider,
  InputNumber as OldInputNumber,
  InputNumberProps,
} from 'antd';
import './index.less';
import classNames from 'classnames';
import { Icon } from '../Icon';
import { AOP } from '../utils/AOP';

interface ExtraProps {
  vertify?: VertifyProps;
  controlsType?: 'horizontal' | 'vertical';
  suffix?: string; // 后缀
}
interface VertifyProps {
  status: 'success' | 'error';
  message?: string;
}

const InputNumber = (
  props: InputNumberProps<number> & {
    children?: React.ReactNode;
  } & {
    ref?: React.Ref<HTMLInputElement> | undefined;
  } & ExtraProps,
) => {
  // 为了与 antd 的生态保持兼容性，我们要求必须要使用 `.@{ant-prefix}` 变量来生成类名
  const { getPrefixCls } = React.useContext(ConfigProvider.ConfigContext);
  const prefixCls = getPrefixCls('btri-input-number');
  const { controlsType = 'vertical', suffix } = props;

  const status = props.vertify?.status;
  const message = props.vertify?.message;

  const [value, setValue] = React.useState<number>(props.value);

  React.useEffect(() => {
    setValue(props.value);
  }, [props.value]);

  const iconSize = React.useMemo(() => {
    const sizes = {
      small: '12px',
      large: '20px',
    };
    return sizes[props.size] || '16px';
  }, [props.size]);

  const statusClassName = React.useMemo(() => {
    let name = prefixCls;

    if (props.size === 'large') {
      name = `${name}-lg`;
    } else if (props.size === 'small') {
      name = `${name}-sm`;
    }
    return name;
  }, [props.size]);

  const newOnChange = new AOP<number, void>(props.onChange)
    .before((numValue) => {
      setValue(numValue);
    })
    .getFunction();

  return (
    <>
      <div>
        {controlsType === 'horizontal' ? (
          <OldInputNumber
            addonBefore={
              <div tabIndex={1} className="iconBox">
                <Icon
                  iconName="MinusBig"
                  style={{
                    cursor: 'pointer',
                    fontSize: `${iconSize}`,
                  }}
                  onClick={() => {
                    newOnChange(value ? value - 1 : -1);
                  }}
                ></Icon>
              </div>
            }
            addonAfter={
              <div tabIndex={0} className="iconBox">
                <Icon
                  iconName="PlusBig"
                  style={{ cursor: 'pointer', fontSize: `${iconSize}` }}
                  onClick={() => {
                    newOnChange(value ? value + 1 : 1);
                  }}
                ></Icon>
              </div>
            }
            controls={false}
            value={value}
            {...props}
            className={classNames(
              `${prefixCls}-box`,
              `${prefixCls}-${status}`,
              statusClassName,
              `${prefixCls}-${controlsType}`,
              props.className,
            )}
            onChange={newOnChange}
          >
            {props.children}
          </OldInputNumber>
        ) : suffix ? (
          <OldInputNumber
            addonAfter={
              <div className={classNames(`${prefixCls}-suffix`)}>{suffix}</div>
            }
            controls={false}
            value={value}
            {...props}
            className={classNames(
              `${prefixCls}-box`,
              statusClassName,
              {
                [`${prefixCls}-suffix-wrapper`]: suffix,
                [`${prefixCls}-${controlsType}`]: !!controlsType,
                [`${prefixCls}-${status}`]: !!status,
              },
              props.className,
            )}
            onChange={newOnChange}
          >
            {props.children}
          </OldInputNumber>
        ) : (
          <OldInputNumber
            controls={{
              upIcon: <Icon iconName="Up" style={{ fontSize: '12px' }}></Icon>,
              downIcon: (
                <Icon iconName="Down" style={{ fontSize: '12px' }}></Icon>
              ),
            }}
            {...props}
            className={classNames(
              `${prefixCls}-box`,
              `${prefixCls}-${status}`,
              statusClassName,
              `${prefixCls}-${controlsType}`,
              props.className,
            )}
          >
            {props.children}
          </OldInputNumber>
        )}

        <div>
          {status && (
            <div
              className={classNames(
                `${prefixCls}-box`,
                `${prefixCls}-${status}`,
                `${prefixCls}-status-box`,
              )}
            >
              <div>{message}</div>
            </div>
          )}
        </div>
      </div>
    </>
  );
};

export { InputNumber };
