var _excluded = ["type", "pre", "readOnly", "disabled", "inputAttribute", "defaultValue", "value", "digits", "max", "min", "placeholder", "maxLength", "autoFocus", "autoSelect", "licon", "liconAttribute", "ricon", "riconAttribute", "clear", "clearReadOnly", "clearAttribute", "rcaption", "children", "onClick", "onCompositionStart", "onCompositionUpdate", "onCompositionEnd", "onInput", "onChange", "onBlur", "onFocus"],
    _excluded2 = ["onClick"];

function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }

function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }

import React, { forwardRef, useRef, useImperativeHandle, useEffect, useState } from 'react';
var InputText = forwardRef(function (_ref, ref) {
  var _ref$type = _ref.type,
      type = _ref$type === void 0 ? 'text' : _ref$type,
      pre = _ref.pre,
      readOnly = _ref.readOnly,
      disabled = _ref.disabled,
      _ref$inputAttribute = _ref.inputAttribute,
      inputAttribute = _ref$inputAttribute === void 0 ? {} : _ref$inputAttribute,
      defaultValue = _ref.defaultValue,
      value = _ref.value,
      digits = _ref.digits,
      max = _ref.max,
      min = _ref.min,
      placeholder = _ref.placeholder,
      maxLength = _ref.maxLength,
      autoFocus = _ref.autoFocus,
      autoSelect = _ref.autoSelect,
      licon = _ref.licon,
      liconAttribute = _ref.liconAttribute,
      ricon = _ref.ricon,
      riconAttribute = _ref.riconAttribute,
      clear = _ref.clear,
      clearReadOnly = _ref.clearReadOnly,
      clearAttribute = _ref.clearAttribute,
      rcaption = _ref.rcaption,
      children = _ref.children,
      onClick = _ref.onClick,
      onCompositionStart = _ref.onCompositionStart,
      onCompositionUpdate = _ref.onCompositionUpdate,
      onCompositionEnd = _ref.onCompositionEnd,
      onInput = _ref.onInput,
      onChange = _ref.onChange,
      onBlur = _ref.onBlur,
      onFocus = _ref.onFocus,
      others = _objectWithoutPropertiesLoose(_ref, _excluded);

  // 清空按钮显示
  var _useState = useState(false),
      clearVisible = _useState[0],
      setClearVisible = _useState[1]; // 节点


  var rootRef = useRef(null);
  var inputRef = useRef(null);
  var preRef = useRef(null);
  useImperativeHandle(ref, function () {
    return rootRef.current;
  }); // 开放内部方法

  if (rootRef.current) {
    rootRef.current.correctNumber = correctNumber;
    rootRef.current.select = _focus;
  } // 开放内部控件


  if (inputRef.current) {
    rootRef.current.input = inputRef.current;
  }

  useEffect(function () {
    var val = inputRef.current.value; // 更新清除按钮和自适应的高度

    updateClear(val);
    preAutoSize(val); // 自动获取焦点

    if (autoFocus) {
      _focus();
    }
  }, []); // eslint-disable-line

  useEffect(function () {
    // 非只读更新清空按钮, 自适应更新文本框高度
    if (!readOnly || !pre) return;
    setTimeout(function () {
      var val = inputRef.current.value; // 更新清除按钮和自适应的高度

      updateClear(val);
      preAutoSize(val);
    }, 100);
  }, [value]); // eslint-disable-line
  // 更新清除按钮

  function updateClear(val) {
    if (typeof val === 'number') {
      val = String(val);
    }

    if (val) {
      setClearVisible(true);
    } else {
      setClearVisible(false);
    }
  } // 自动扩充功能


  function preAutoSize(val) {
    if (!pre) return;
    preRef.current.children[0].innerText = val;
    inputRef.current.style.height = preRef.current.clientHeight + 'px';
  } // 校验maxLength


  function correctNumber(val) {
    if (typeof val === 'number') val = String(val); // 最大长度

    if (maxLength && val && val.length > maxLength) {
      val = val.substring(0, maxLength);
    } // 小数位截取


    if (typeof digits === 'number') {
      if (val.indexOf('.') !== -1) {
        val = val.substring(0, val.indexOf('.') + Number(digits) + 1);
      }
    }

    return val;
  } // 获取焦点


  function _focus() {
    if (disabled || readOnly || !inputRef.current) return;
    inputRef.current.focus(); // 只有获取焦点以后才能选中

    if (autoSelect) {
      inputRef.current.select();
    }
  } // 获取焦点时, 如果readOnly或者disabled时, 需要立即失去焦点, 解决ios会出现底栏的问题


  function handleFocus(e) {
    if (readOnly || disabled) {
      e.target.blur();
      return;
    }

    if (onFocus) onFocus(e);
  } // 清空按钮控制


  function handleInput(event) {
    var e = event.nativeEvent; // 修改值时有渲染延迟, 更新清空按钮和自适应的高度

    setTimeout(function () {
      updateClear(e.target.value);
      preAutoSize(e.target.value);
    }, 100); // Callback

    if (onInput) onInput(e, e.target.value);
  } // 修改值回调


  function handleChange(e, value, callback) {
    var _target$validity;

    var target = e.target;
    var val = typeof value === 'string' || typeof value === 'number' ? value : target.value; // 输入值不合法

    if (target === null || target === void 0 ? void 0 : (_target$validity = target.validity) === null || _target$validity === void 0 ? void 0 : _target$validity.badInput) {
      val = '';
    } // 校验maxLength


    if (val !== '') {
      val = correctNumber(val);
    } // 非受控组件需要操作DOM


    if (defaultValue || defaultValue === '') {
      e.target.value = val;
    } // 回调


    if (callback) {
      callback(e, val);
    }
  } // 数值框失去焦点, 校验最大值和最小值


  function handleBlur(e) {
    if (readOnly || disabled) {
      return;
    }

    var target = e.target;
    var val = target.value;

    if (val && !isNaN(val)) {
      // 输入时只校验最大值、小数点、最大长度、返回错误
      if (typeof max === 'number') {
        if (Number(val) > Number(max)) val = max;
      }

      if (typeof min === 'number') {
        if (Number(val) < Number(min)) val = min;
      } // 纠正数字


      if (type === 'number') {
        val = '' + Number(val);
      } // 修改完回调


      if (val !== value) {
        handleChange(e, val, onChange);
      }
    }

    if (onBlur) onBlur(e);
  } // 点击容器


  function handleClick(e) {
    var elInput = inputRef.current;
    if (!elInput) return;
    if (disabled) return;
    var target = e.target;

    if (target.classList.contains('clearicon')) {
      handleClear(e);
      e.stopPropagation();
      return;
    }

    if (target.classList.contains('licon') && liconAttribute && liconAttribute.onClick) {
      liconAttribute.onClick(e, elInput.value);
      e.stopPropagation();
      return;
    }

    if (target.classList.contains('ricon') && riconAttribute && riconAttribute.onClick) {
      riconAttribute.onClick(e, elInput.value);
      e.stopPropagation();
      return;
    }

    if (target.classList.contains('input-text') && inputAttribute.onClick) {
      inputAttribute.onClick(e, elInput.value);
      e.stopPropagation();
      return;
    }

    if (onClick) {
      onClick(e, elInput.value);
      e.stopPropagation();
    }
  } // 点击清除


  function handleClear(event) {
    // 获取焦点
    _focus(); // 清除回调


    var e = {
      target: inputRef.current
    };
    if (clear && typeof clear === 'function') clear(e, '');else if (clearReadOnly && typeof clearReadOnly === 'function') clearReadOnly(e, ''); // Callback

    if (onChange) {
      handleChange(e, '', onChange);
    } else if (!value) {
      // 有value没有onChange本身就清空不掉, 所以要控制这种情况不允许清空
      e.target.value = '';
    } // 修改值时有渲染延迟, 更新清空按钮和自适应的高度


    setTimeout(function () {
      updateClear(e.target.value);
      preAutoSize(e.target.value);
    }, 100);
    event.stopPropagation();
  } // render


  function getInputDOM() {
    // 剔除掉onClick事件, 因为在容器onClick已经回调了
    var otherInputAttribute = filterProps(inputAttribute); // pre类型

    if (pre) {
      // pre的左右padding
      var preLeft = 0;
      var preRight = 0;

      if (otherInputAttribute.style) {
        if (otherInputAttribute.style.padding) {
          var paddingValues = otherInputAttribute.style.padding.split(' ');

          if (paddingValues.length === 1) {
            preLeft = paddingValues[0];
            preRight = paddingValues[0];
          } else if (paddingValues.length === 2) {
            preLeft = paddingValues[1];
            preRight = paddingValues[1];
          } else if (paddingValues.length === 4) {
            preLeft = paddingValues[1];
            preRight = paddingValues[3];
          }
        } else if (otherInputAttribute.style.paddingLeft || otherInputAttribute.style.paddingRight) {
          preLeft = otherInputAttribute.style.paddingLeft || '0';
          preRight = otherInputAttribute.style.paddingRight || '0';
        }
      }

      return /*#__PURE__*/React.createElement("div", _extends({}, otherInputAttribute, {
        className: "input-pre-box" + (otherInputAttribute.className ? ' ' + otherInputAttribute.className : '')
      }), /*#__PURE__*/React.createElement("textarea", {
        ref: inputRef,
        autoFocus: autoFocus,
        value: value,
        defaultValue: defaultValue,
        maxLength: maxLength,
        readOnly: readOnly,
        disabled: disabled,
        className: "input-pre",
        placeholder: placeholder,
        onChange: onChange ? function (e) {
          return handleChange(e, null, onChange);
        } : null,
        onCompositionStart: onCompositionStart ? function (e) {
          return handleChange(e, null, onCompositionStart);
        } : null,
        onCompositionUpdate: onCompositionUpdate ? function (e) {
          return handleChange(e, null, onCompositionUpdate);
        } : null,
        onCompositionEnd: onCompositionEnd ? function (e) {
          return handleChange(e, null, onCompositionEnd);
        } : null,
        onInput: handleInput,
        onBlur: handleBlur,
        onFocus: handleFocus
      }), /*#__PURE__*/React.createElement("pre", {
        ref: preRef,
        style: {
          left: preLeft,
          right: preRight
        }
      }, /*#__PURE__*/React.createElement("span", null)));
    } // textarea类型


    if (type === 'textarea') {
      // 如果值绑定属性,则只有通过父组件的prop来改变值
      return /*#__PURE__*/React.createElement("textarea", _extends({
        ref: inputRef
      }, otherInputAttribute, {
        autoFocus: autoFocus,
        value: value,
        defaultValue: defaultValue,
        maxLength: maxLength,
        readOnly: readOnly,
        disabled: disabled,
        placeholder: placeholder,
        onChange: onChange ? function (e) {
          return handleChange(e, null, onChange);
        } : null,
        onCompositionStart: onCompositionStart ? function (e) {
          return handleChange(e, null, onCompositionStart);
        } : null,
        onCompositionUpdate: onCompositionUpdate ? function (e) {
          return handleChange(e, null, onCompositionUpdate);
        } : null,
        onCompositionEnd: onCompositionEnd ? function (e) {
          return handleChange(e, null, onCompositionEnd);
        } : null,
        onInput: handleInput,
        onBlur: handleBlur,
        onFocus: handleFocus,
        className: "input-area" + (otherInputAttribute.className ? ' ' + otherInputAttribute.className : '')
      }));
    } // 其它类型


    return /*#__PURE__*/React.createElement("input", _extends({
      ref: inputRef,
      type: type
    }, otherInputAttribute, {
      className: "input-text" + (otherInputAttribute.className ? ' ' + otherInputAttribute.className : ''),
      defaultValue: defaultValue,
      value: value,
      min: typeof min === 'number' ? min : '',
      max: typeof max === 'number' ? max : '',
      maxLength: maxLength,
      disabled: disabled,
      readOnly: readOnly,
      placeholder: placeholder,
      onChange: onChange ? function (e) {
        return handleChange(e, null, onChange);
      } : null,
      onCompositionStart: onCompositionStart ? function (e) {
        return handleChange(e, null, onCompositionStart);
      } : null,
      onCompositionUpdate: onCompositionUpdate ? function (e) {
        return handleChange(e, null, onCompositionUpdate);
      } : null,
      onCompositionEnd: onCompositionEnd ? function (e) {
        return handleChange(e, null, onCompositionEnd);
      } : null,
      onInput: handleInput,
      autoFocus: autoFocus,
      onBlur: handleBlur,
      onFocus: handleFocus
    }));
  } // 过滤已经回调的属性


  function filterProps(props) {
    if (!props) return {};

    var onClick = props.onClick,
        otherProps = _objectWithoutPropertiesLoose(props, _excluded2);

    return _extends({}, otherProps);
  } // 剔除掉onClick事件, 因为在容器onClick已经回调了


  var otherLiconAttribute = filterProps(liconAttribute);
  var otherRiconAttribute = filterProps(riconAttribute);
  var otherClearAttribute = filterProps(clearAttribute);
  return /*#__PURE__*/React.createElement("div", _extends({
    ref: rootRef
  }, others, {
    className: "input-text-box" + (others.className ? ' ' + others.className : ''),
    onClick: handleClick
  }), licon && licon, liconAttribute && /*#__PURE__*/React.createElement("i", _extends({}, otherLiconAttribute, {
    className: "licon icon" + (otherLiconAttribute.className ? ' ' + otherLiconAttribute.className : '')
  })), getInputDOM(), children && children, clearVisible && (clearReadOnly || clear) && (clearReadOnly || !readOnly) && !disabled && /*#__PURE__*/React.createElement("i", _extends({}, otherClearAttribute, {
    className: "icon clearicon" + (otherClearAttribute.className ? ' ' + otherClearAttribute.className : ' ricon close-icon-clear size18')
  })), riconAttribute && /*#__PURE__*/React.createElement("i", _extends({}, otherRiconAttribute, {
    className: "ricon icon" + (otherRiconAttribute.className ? ' ' + otherRiconAttribute.className : '')
  })), ricon && ricon, rcaption && rcaption);
});
export default InputText;