/* eslint-disable @typescript-eslint/no-unsafe-assignment */
/* eslint-disable @typescript-eslint/restrict-template-expressions */
/* eslint-disable @typescript-eslint/ban-ts-comment */
import React, { KeyboardEvent } from 'react';
import { useControllableValue } from 'ahooks';
import classnames from 'classnames';

import './index.scss';

const numReg = /^\d\d*.?\d*\d$|\d/;

interface NumberPropsI {
  value?: string;
  onChange: (val: string) => string;
  className?: string;
  style?: object;
  width: number;
  align: 'left' | 'right';
  placeholder: string;
  onFocus: () => void;
  onBlur: () => void;
  onEnter: (value: any, e: KeyboardEvent) => void;
  min: number;
  max: number;
  format: (value: any) => any;
  // 当数据经过修正后的回调
  onCorrect?: (currentValue: string, oldValue: string) => void;
}

const numberFormat = (val: string): string => {
  let ret = val.replace(/[^0-9.]/g, '');
  if (ret.indexOf('.') !== ret.lastIndexOf('.')) {
    // 存在多个小数点
    const splitArr = ret.split('.');
    ret = splitArr.reduce(
      (resStr, nextStr, index) =>
        `${resStr}${index === 1 ? '.' : ''}${nextStr}`,
      '',
    );
  }
  return ret.replace(/^00+\./, '0.').replace(/^00+/, '0'); // 多个0合并成一个
};

/**
 *
 * @param props
 * @returns
 * 格式化顺序和优先级
 *   1、通用格式化 --- 会先做简单的格式处理，过滤一些非数字信息或者写法不正确的情况
 *   2、自定义格式化 --- 优先级是 format 》 min|max
 */
export default function Number(props: NumberPropsI) {
  const {
    className,
    style,
    width = '100%',
    align = 'left',
    placeholder = '请输入',
    onFocus,
    onBlur,
    onEnter,
    min,
    max,
    format,
    onCorrect,
    ...rest
  } = props;

  const [value, onChange] = useControllableValue(props);

  const customFormat = (value: string): string => {
    if (numReg.test(value)) {
      // 符合数字校验，则做自定义格式
      let numValue = parseFloat(value);
      if (min) {
        numValue = Math.max(min, numValue);
      }
      if (max) {
        numValue = Math.min(max, numValue);
      }
      return String(numValue);
    }
    return value;
  };

  const onMidChange = (event: object) => {
    // @ts-ignore
    const target = event.target as HTMLInputElement;
    const val = target.value;
    // 修复非数字字符串
    const numberValue = numberFormat(val);
    // 修复最大最小值
    const customerValue = customFormat(numberValue);
    // 格式化数字
    let formattedValue = customerValue;
    if (format instanceof Function) {
      const formatValue = format(formattedValue);
      if (numReg.test(formatValue as string)) {
        formattedValue = formatValue;
      }
    }
    onChange(formattedValue);
    if (`${val}` !== customerValue) {
      onCorrect instanceof Function && onCorrect(customerValue, val);
    }
  };

  const onKeyDown = (event: KeyboardEvent) => {
    if (event.keyCode === 13) {
      // enter 事件
      onEnter instanceof Function && onEnter(value, event);
    }
  };

  const finalClassName = classnames('op-number', className);
  const finalStyle = {
    ...(style || {}),
    width,
    textAlign: align,
  };
  return (
    <input
      data-hottag='cn-op.number'
      {...rest}
      className={finalClassName}
      value={value}
      style={finalStyle}
      onChange={onMidChange}
      onKeyDown={onKeyDown}
      placeholder={placeholder}
      type='text'
      onFocus={onFocus}
      onBlur={onBlur}
      onClick={(e) => {
        e.stopPropagation(); // 阻止冒泡
      }}
    />
  );
}
