import PropTypes from "prop-types";
import React from "react";
import $calc from "../../utils/common";
import styleObj from "./index.module.scss";

export default class CalcInput extends React.Component {
  //#region 属性 & 构造函数

  // 属性类型校验
  static propTypes = {
    lv: PropTypes.number,
    value: PropTypes.string,
    type: PropTypes.string,
    isPassword: PropTypes.bool,
    placeholder: PropTypes.string,
    compId: PropTypes.string,
    customClass: PropTypes.string,
    width: PropTypes.string,
    height: PropTypes.string,
    showErrorTip: PropTypes.bool,
    errorTip: PropTypes.string,
    onChangeEvent: PropTypes.func,
    onUpdateInputTypeEvent: PropTypes.func,
    onKeyUpEvent: PropTypes.func,
  };
  // 属性默认值
  static defaultProps = {
    lv: 7,
    value: "",
    type: "text",
    isPassword: false,
    placeholder: "Please input",
    compId: "calc-input",
    width: "",
    height: "40px",
    showErrorTip: false,
    errorTip: "",
    onChangeEvent: (e) => {
      console.log(e.target.value);
    },
    onUpdateInputTypeEvent: (showPassword) => {
      console.log(`trigger onUpdateInputTypeEvent`, showPassword);
    },
    onKeyUpEvent: (e) => {
      // console.log(e.keyCode);
    },
    customClass: "custom-calc-input",
  };

  constructor(props) {
    super(props);
    this.state = {
      showPassword: false,
    };
  }

  //#endregion

  //#region hooks

  render() {
    // console.log("input render...");
    const _self = this;
    const {
      lv,
      value,
      type,
      isPassword,
      placeholder,
      compId,
      children,
      onChangeEvent,
      // 修改输入框类型, 仅监听isPassword=true的输入框
      onUpdateInputTypeEvent,
      onKeyUpEvent,
      customClass,
      showErrorTip,
      errorTip,
    } = _self.props;
    const slotObj = $calc.tool.getNamedSlots(children);
    const dom = (
      //   <div className="calc-comp-input">
      <div className={`${styleObj["calc-comp-input-scoped"]}`}>
        <div className="calc-comp-input">
          <div className="comp-input-wrap">
            {slotObj["prefix"]}
            {slotObj["default"] ? (
              slotObj["default"]
            ) : (
              <input
                className={`calc-input ${isPassword ? "show-password" : ""} ${
                  $calc.tool.isNullOrEmpty(customClass) ? "" : customClass
                }`}
                autocomplete="new-password"
                id={compId}
                type={type}
                value={value}
                placeholder={placeholder}
                style={_self.getStyleObj()}
                onChange={(e) => {
                  onChangeEvent && onChangeEvent(e);
                }}
                onKeyUp={(e) => {
                  onKeyUpEvent && onKeyUpEvent(e);
                }}
              ></input>
            )}
            {isPassword && (
              <i
                className={`icon-input icon-input-handle-password ${
                  _self.state.showPassword
                    ? "calc-oa-pw_shown"
                    : "calc-oa-pw_hide"
                }`}
                onClick={() => {
                  _self.toggleShowPassword(
                    !_self.state.showPassword,
                    (showPassword) => {
                      // 修改input类型
                      onUpdateInputTypeEvent &&
                        onUpdateInputTypeEvent(showPassword);
                    }
                  );
                }}
              ></i>
            )}
          </div>
          {showErrorTip && !$calc.tool.isNullOrEmpty(errorTip) && (
            <div className="error-tip-wrap">
              <span className="tip-text" title={errorTip}>
                {errorTip}
              </span>
            </div>
          )}
        </div>
      </div>
    );
    return dom;
  }

  componentDidMount() {
    // console.log("input componentDidMount...");
  }
  shouldComponentUpdate(nextProps, nextState) {
    const _self = this;
    // 若子组件无属性变化及状态更新, 则无需更新组件
    // Immutable验证的效果不好, 用回JSON.stringify来处理, 排除掉循环引用的属性, 如插槽
    const removeProps = ["children"];
    const nextPropsClone = $calc.tool.deepClone(nextProps, removeProps);
    const curPropsClone = $calc.tool.deepClone(_self.props, removeProps);

    const nextStateClone = $calc.tool.deepClone(nextState, removeProps);
    const curnextStateClone = $calc.tool.deepClone(_self.state, removeProps);

    const needRender =
      JSON.stringify(nextPropsClone) != JSON.stringify(curPropsClone) ||
      JSON.stringify(nextStateClone) != JSON.stringify(curnextStateClone);
    // console.log("calc-input shouldComponentUpdate...", needRender);
    if (needRender) {
      return true;
    }

    return false;
    // return true;
  }
  componentDidUpdate(preProps, preState) {
    // console.log("input componentDidUpdate...");
  }
  componentWillUnmount() {
    // console.log("input shouldComponentUpdate...");
  }

  //#endregion

  //#region methods

  /**
   * 显示/隐藏密码
   * @param {boolean} isShow 显示/隐藏
   * @param {function} callBack 回调函数
   * @return {void}
   */
  toggleShowPassword(isShow = false, callBack) {
    const _self = this;
    _self.setState(
      {
        showPassword: isShow,
      },
      () => {
        callBack && callBack(_self.state.showPassword);
      }
    );
  }

  // 获取样式对象
  getStyleObj() {
    const _self = this;
    let styleObj = {};
    const { width, height } = _self.props;

    // 设置width
    if (!$calc.tool.isNullOrEmpty(width)) {
      styleObj["width"] = $calc.tool.isNum(width) ? `${width}px` : width;
    }

    // 设置height
    if (!$calc.tool.isNullOrEmpty(height)) {
      styleObj["height"] = $calc.tool.isNum(height)
        ? `${height}px`
        : (styleObj["height"] = height);
    }

    return styleObj;
  }

  //#endregion
}
