import React, { useState, memo, useEffect } from 'react';
import { Input, View, Image } from '@tarojs/components';
import { debounce } from 'lodash';

const reduce = 'https://wanmi-b2b-x-site.oss-cn-shanghai.aliyuncs.com/pandora-ui/assets/components/images/stepper/icon-reduce.png';
const reduceDisabled = 'https://wanmi-b2b-x-site.oss-cn-shanghai.aliyuncs.com/pandora-ui/assets/components/images/stepper/icon-reduce-disabled.png';
const add = 'https://wanmi-b2b-x-site.oss-cn-shanghai.aliyuncs.com/pandora-ui/assets/components/images/stepper/icon-add.png';
const addDisabled = 'https://wanmi-b2b-x-site.oss-cn-shanghai.aliyuncs.com/pandora-ui/assets/components/images/stepper/icon-add-disabled.png';

export interface IStepperProps {
  /** 默认值 */
  count?: number;
  /** 最小值 */
  min?: number;
  /** 最大值 */
  max?: number;
  /** 输入框是否可用 */
  inputDisabled?: boolean;
  /** 禁用 */
  disabled?: boolean;
  isNumber?: boolean;
  /** 回调方法 */
  getNum: (count: number, flag?: boolean) => void;
  // 点击加号、减号、input输入框输入内容时，在render前，拦截处理value
  handleValue?: (obj: {
    // type操作类型 - 加号add、减号minus、文本输入input
    type: string;
    // 当前value
    currentValue: number;
    // 下一个value，即：加1 或 减1后的value
    nextValue?: number;
  }) => number;
}

export interface IStepperState {
  number: number;
}

/**
 * 步进器组件
 */
// 是否正在执行中
let isRun = false;
const Stepper: React.FC<IStepperProps> = ({
  count = 0,
  min = 0,
  max = 999,
  inputDisabled = false,
  disabled = false,
  isNumber = false, //是否支持输入小数
  getNum = (_count: number, _flag?: boolean) => {},
  handleValue = (obj: {
    type: string;
    currentValue: number;
    nextValue?: number;
  }) => undefined,
}) => {
  // 考虑输入框和按钮两种录入方式，使用useReducer时type类型不统一
  // 仅第一次同步尝试修正count，等效于defaultValue
  const [number, setNumber] = useState<number>(() => {
    const defaultValue = count > max ? max : (min > count ? min : count) || 0;
    if (defaultValue !== count) {
      getNum(Number(defaultValue));
    }
    return defaultValue;
  });
  // renderKey用于强制更新Input组件
  const [renderKey, setRenderKey] = useState(0);

  /* eslint-disable */
  useEffect(() => {
    if (count !== number){
      if(count < min){
        getNum(Number(min))
        setNumber(Number(min));
      } else if(count > max){
        getNum(Number(max))
        setNumber(Number(max));
      } else {
        setNumber(Number(count));
      }
    }
  }, [count]);
  /* eslint-enable */

  /**
   * 输入失焦
   * @param e
   */
  const onBlur = (e) => {
    if (isRun) {
      return;
    }
    isRun = true;

    let num =
      e.detail.value === '' || e.detail.value === '-'
        ? 0
        : isNumber
        ? Number(e.detail.value)
        : Number(e.detail.value).toFixed(0);

    num = num || min;
    let result = checkNum(num);
    if (num) {
      // 通过handleValue方法外部处理value
      const val = handleValue({
        type: 'input',
        currentValue: checkNum(num),
        nextValue: checkNum(num),
      });
      // 当val为undefined 或 null时，用result
      result = checkNum(val ?? result);
    }

    setNumber(result);

    // 用于解决某种情况下输入框输入，如：06，input输入框失去焦点时，输入框依旧展示06，正确的是展示6
    if (e.detail.value || result !== number) {
      getNum(result);
    }

    /**
     * 强制更新Input组件
     * 用于解决当number、result都为0，.detail.value为''时，input输入框失去焦点时输入框空白的问题；
     */
    setRenderKey(Date.now());

    setTimeout(() => {
      isRun = false;
    }, 1000);
  };

  /**
   * 输入
   * @param e
   */
  const onChange = (e) => {
    if (e.detail.value === '') {
      return;
    }
    const num = e.detail.value === '-' ? 0 : Number(e.detail.value);
    if (num > max) {
      setNumber(num);
    } else if (min > num) {
      setNumber(num);
    } else {
      setNumber(num);
    }
  };

  const reduceNum = (e) => {
    e.stopPropagation();
    if (isRun) {
      return;
    }

    let result = checkNum(Number(number) - 1);
    // 当前value
    const currentValue = checkNum(Number(number));
    // 下一个value，即：加1 或 减1后的value
    const nextValue = checkNum(Number(number) - 1);
    // 通过handleValue方法外部处理value
    const val = handleValue({
      type: 'minus',
      currentValue,
      nextValue,
    });
    // 当val为undefined 或 null时，用result
    result = checkNum(val ?? result);

    setNumber(result);
    getNum(result, false);
  };

  const addNum = (e) => {
    e.stopPropagation();
    if (isRun) {
      return;
    }

    let result = checkNum(Number(number) + 1);
    // 当前value
    const currentValue = checkNum(Number(number));
    // 下一个value，即：加1 或 减1后的value
    const nextValue = checkNum(Number(number) + 1);
    // 通过handleValue方法外部处理value
    const val = handleValue({
      type: 'add',
      currentValue,
      nextValue,
    });
    // 当val为undefined 或 null时，用result
    result = checkNum(val ?? result);

    setNumber(result);
    getNum(result, true);
  };

  /**
   * 校验数量合法性
   * @param num
   */
  const checkNum = (num) => {
    if (num > max) {
      return max;
    } else if (num < min) {
      return min;
    } else if (num === '' || num <= 0) {
      return 0;
    }
    return num;
  };
  return (
    <View className='wm-stepper' onClick={(e) => e.stopPropagation()}>
      {disabled || Number(number) === min || Number(number) === 0 ? (
        <View className='reduce-box'>
          <View className='icon'>
            <Image className='reduce' src={reduceDisabled} />
          </View>
        </View>
      ) : (
        <View className='reduce-box'>
          {/**可点击区域 */}
          <View
            className='click-area'
            onClick={number ? reduceNum : (e) => e.stopPropagation()}
          />
          <View className='icon'>
            <Image className='reduce' src={reduce} />
          </View>
        </View>
      )}
      {!(inputDisabled || disabled) ? (
        <Input
          key={renderKey}
          className='input'
          value={number.toString()}
          type='number'
          onClick={(e) => e.stopPropagation()}
          onInput={onChange}
          onBlur={onBlur}
          maxlength={7}
        />
      ) : (
        <Input className='int' value={number.toString()} type='text' disabled />
      )}
      {disabled || number >= max ? (
        <View className='add-box'>
          <View className='icon'>
            <Image className='add' src={addDisabled} />
          </View>
        </View>
      ) : (
        <View className='add-box'>
          {/**可点击区域 */}
          <View className='click-area' onClick={addNum} />
          <View className='icon'>
            <Image className='add' src={add} />
          </View>
        </View>
      )}
    </View>
  );
};

/**
 * 减少列表不必要渲染 等效于shouldComponentUpdate
 * @param prevProps
 * @param nextProps
 */
const equal = (prevProps, nextProps) => {
  return JSON.stringify(prevProps) === JSON.stringify(nextProps);
};

export default memo(Stepper, equal);
