"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
exports.__esModule = true;
exports["default"] = void 0;
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
var _inheritsLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/inheritsLoose"));
var _balloon = _interopRequireDefault(require("@alifd/next/lib/balloon"));
var _select = _interopRequireDefault(require("@alifd/next/lib/select"));
var _react = _interopRequireWildcard(require("react"));
var _propTypes = _interopRequireDefault(require("prop-types"));
var _lowcodeEngine = require("@alilc/lowcode-engine");
var acorn = _interopRequireWildcard(require("acorn"));
var _utils = require("./locale/utils");
var _zhCN = _interopRequireDefault(require("./locale/zh-CN"));
require("./index.less");
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); }
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { "default": e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n["default"] = e, t && t.set(e, n), n; }
function _createForOfIteratorHelperLoose(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (it) return (it = it.call(o)).next.bind(it); if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; return function () { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
var Option = _select["default"].Option,
  AutoComplete = _select["default"].AutoComplete;
var Tooltip = _balloon["default"].Tooltip;
var helpMap = {
  "this": '容器上下文对象',
  state: '容器的state',
  props: '容器的props',
  context: '容器的context',
  schema: '页面上下文对象',
  component: '组件上下文对象',
  constants: '应用常量对象',
  utils: '应用工具对象',
  dataSourceMap: '容器数据源Map',
  field: '表单Field对象'
};
var ExpressionView = exports["default"] = /*#__PURE__*/function (_PureComponent) {
  function ExpressionView(props) {
    var _this;
    _this = _PureComponent.call(this, props) || this;
    _this.expression = void 0;
    _this.i18n = void 0;
    _this.t = void 0;
    _this.$input = void 0;
    _this.listenerFun = void 0;
    _this.expression = /*#__PURE__*/_react["default"].createRef();
    _this.i18n = (0, _utils.generateI18n)(props.locale, props.messages);
    _this.state = {
      value: ExpressionView.getInitValue(props.value),
      dataSource: props.dataSource || []
    };
    return _this;
  }

  // static getDerivedStateFromProps(props: { value: any }, state: { preValue: any }) {
  //   const curValue = ExpressionView.getInitValue(props.value);
  //   if (curValue !== state.preValue) {
  //     return {
  //       preValue: curValue,
  //       value: curValue,
  //     };
  //   }
  //   return null;
  // }
  (0, _inheritsLoose2["default"])(ExpressionView, _PureComponent);
  ExpressionView.getInitValue = function getInitValue(val) {
    if ((0, _utils.isJSExpression)(val)) {
      if (typeof val === 'object') {
        return val.value;
      } else if (typeof val === 'string') {
        var arr = val.match(/^\{\{(.*?)\}\}$/);
        if (arr) return arr[1];
      }
    }
    return val;
  };
  var _proto = ExpressionView.prototype;
  _proto.onChange = function onChange(value) {
    var _this2 = this;
    var realInputValue = value;
    var realDataSource = null;
    var nextCursorIndex;
    // 更新值
    // if (actionType === 'itemClick' || actionType === 'enter') {
    //   // const curValue = this.state.value;
    //   // if (curValue) {
    //   //   realInputValue = curValue + realInputValue;
    //   // }
    // }
    // 更新数据源
    var newState = {
      value: realInputValue
    };
    if (realDataSource !== null) newState.dataSource = realDataSource;
    this.setState(newState, function () {
      nextCursorIndex && _this2.setInputCursorPosition(nextCursorIndex);
    });
    // 默认加上变量表达式
    this.t && clearTimeout(this.t);
    this.t = setTimeout(function () {
      var onChange = _this2.props.onChange;
      // realInputValue = realInputValue ? `{{${realInputValue}}}` : undefined;
      onChange && onChange({
        type: 'JSExpression',
        value: realInputValue
      });
    }, 300);
  }

  /**
   * 获取AutoComplete数据源
   * @param  {String}
   * @return {Array}
   */;
  _proto.getDataSource = function getDataSource() {
    var _schema$componentsTre;
    var schema = _lowcodeEngine.project.exportSchema();
    var stateMap = schema.componentsTree[0].state;
    var dataSource = [];
    var datasourceMap = (_schema$componentsTre = schema.componentsTree[0]) === null || _schema$componentsTre === void 0 ? void 0 : _schema$componentsTre.dataSource;
    var list = (datasourceMap === null || datasourceMap === void 0 ? void 0 : datasourceMap.list) || [];
    for (var key in stateMap) {
      dataSource.push("this.state." + key);
    }
    for (var _iterator = _createForOfIteratorHelperLoose(list), _step; !(_step = _iterator()).done;) {
      var item = _step.value;
      if (item && item.id) {
        dataSource.push("this.state." + item.id);
      }
    }
    return dataSource;
  }

  /**
   * 获取光标前的对象字符串，语法解析获取对象字符串
   * @param  {String} str 模板字符串
   * @return {String}     光标前的对象字符串
   */;
  _proto.getCurrentFiled = function getCurrentFiled(str) {
    str += 'x'; // .后面加一个x字符，便于acorn解析
    try {
      var astTree = acorn.parse(str);
      var right = astTree.body[0].expression.right || astTree.body[0].expression;
      if (right.type === 'MemberExpression') {
        var start = right.start,
          end = right.end;
        str = str.slice(start, end);
        return {
          str: str,
          start: start,
          end: end
        };
      }
    } catch (e) {
      return null;
    }
  }

  /**
   * 获取输入的上下文信息
   * @param  {Array}
   * @return {Array}
   */;
  _proto.getContextKeys = function getContextKeys(keys) {
    var editor = this.props.field.editor;
    var limitKeys = ['schema', 'utils', 'constants'];
    if (keys.length === 0) return limitKeys;
    if (!limitKeys.includes(keys[0])) return [];
    var result = [];
    var keyValue = editor;
    var assert = false;
    keys.forEach(function (item) {
      if (!keyValue[item] || typeof keyValue[item] !== 'object') {
        assert = true;
      }
      if (keyValue[item]) {
        keyValue = keyValue[item];
      }
    });
    if (assert) return [];
    result = Object.keys(keyValue);
    return result;
    // return utilsKeys.concat(constantsKeys).concat(schemaKeys);
  }

  /* 过滤key */;
  _proto.filterKey = function filterKey(obj, name) {
    var filterKeys = ['reloadDataSource', 'REACT_HOT_LOADER_RENDERED_GENERATION', 'refs', 'updater', 'appHelper', 'isReactComponent', 'forceUpdate', 'setState', 'isPureReactComponent'];
    var result = [];
    for (var key in obj) {
      if (key.indexOf('_') !== 0 && filterKeys.indexOf(key) === -1) {
        result.push(name + "." + key);
      }
    }
    return result;
  }

  /**
   * 根据输入项进行筛选
   * @param  {String}
   * @param  {String}
   * @return {Boolen}
   */;
  _proto.filterOption = function filterOption(inputValue, item) {
    var cursorIndex = this.getInputCursorPosition();
    if (typeof inputValue != 'string') return false;
    var preStr = inputValue.substr(0, cursorIndex);
    var lastKey = preStr.split('.').slice(-1);
    if (!lastKey) return true;
    if (item.value.indexOf(lastKey) > -1) return true;
    return false;
  }

  // handleClick = () => {
  //   this.props.field.editor.emit('variableBindDialog.open');
  // }
  ;
  _proto.render = function render() {
    var _this$state = this.state,
      value = _this$state.value,
      dataSource = _this$state.dataSource;
    var placeholder = this.props.placeholder;
    var isValObject = !!(value == '[object Object]');
    var title = isValObject ? this.i18n('valueIllegal') : (value || placeholder || this.i18n('jsExpression')).toString();
    var cursorIndex = this.getInputCursorPosition();
    var childNode = cursorIndex ? /*#__PURE__*/_react["default"].createElement("div", {
      className: "cursor-blink"
    }, title.substr(0, cursorIndex), /*#__PURE__*/_react["default"].createElement("b", null, "|"), title.substr(cursorIndex)) : title;
    return /*#__PURE__*/_react["default"].createElement("div", {
      ref: this.expression,
      style: {
        width: '100%',
        display: 'inline-block'
      }
    }, /*#__PURE__*/_react["default"].createElement(Tooltip, {
      triggerType: isValObject ? ['click'] : ['focus'],
      align: "tl",
      popupClassName: "code-input-overlay",
      trigger: isValObject ? value : /*#__PURE__*/_react["default"].createElement("div", null, /*#__PURE__*/_react["default"].createElement(AutoComplete, (0, _extends2["default"])({
        size: "small"
      }, this.props, {
        style: {
          width: '100%'
        },
        dataSource: dataSource,
        placeholder: placeholder || this.i18n('jsExpression'),
        value: value,
        disabled: isValObject,
        innerBefore: /*#__PURE__*/_react["default"].createElement("span", {
          style: {
            color: '#999',
            marginLeft: 4
          }
        }, '{{'),
        innerAfter: /*#__PURE__*/_react["default"].createElement("span", {
          style: {
            color: '#999',
            marginRight: 4
          }
        }, '}}'),
        popupClassName: "expression-setter-item-inner"
        // eslint-disable-next-line no-shadow
        ,
        itemRender: function itemRender(itemValue) {
          return /*#__PURE__*/_react["default"].createElement(Option, {
            key: itemValue.value,
            text: itemValue.label,
            value: itemValue.value
          }, /*#__PURE__*/_react["default"].createElement("div", {
            className: "code-input-value"
          }, itemValue.value), /*#__PURE__*/_react["default"].createElement("div", {
            className: "code-input-help"
          }, helpMap[itemValue.value]));
        },
        onChange: this.onChange.bind(this),
        filter: this.filterOption.bind(this)
      })))
    }, childNode));
  };
  _proto.componentDidMount = function componentDidMount() {
    var _this3 = this;
    this.$input = this.findInputElement();
    if (this.$input) {
      this.listenerFun = function (event) {
        var isMoveKey = !!(event.type == 'keyup' && ~[37, 38, 39, 91].indexOf(event.keyCode));
        var isMouseup = event.type == 'mouseup';
        if (isMoveKey || isMouseup) {
          // eslint-disable-next-line react/no-access-state-in-setstate
          var dataSource = _this3.getDataSource(_this3.state.value) || [];
          _this3.setState({
            dataSource: dataSource
          });
        }
      };
      this.$input.addEventListener('keyup', this.listenerFun, false);
      this.$input.addEventListener('mouseup', this.listenerFun, false);
    }
  };
  _proto.componentWillUnmount = function componentWillUnmount() {
    if (this.listenerFun && this.$input) {
      this.$input.removeEventListener('keyup', this.listenerFun, false);
      this.$input.removeEventListener('mouseup', this.listenerFun, false);
    }
  }

  /**
   * 获取Input输入框DOM节点
   */;
  _proto.findInputElement = function findInputElement() {
    return this.expression.current.children[0].getElementsByTagName('input')[0];
  }

  /**
   * 获取光标位置
   *
   */;
  _proto.getInputCursorPosition = function getInputCursorPosition() {
    if (!this.$input) return;
    return this.$input.selectionStart;
  }

  /*
   * 字符串取得对象keys
   */;
  _proto.getObjectKeys = function getObjectKeys(str) {
    var keys = [];
    if (str) keys = str.split('.');
    return keys.slice(0, keys.length - 1);
  }

  /*
   * 设置input组件光标位置在闭合}前
   */;
  _proto.setInputCursorPosition = function setInputCursorPosition(idx) {
    this.$input.setSelectionRange(idx, idx);
    this.forceUpdate();
  };
  return ExpressionView;
}(_react.PureComponent);
ExpressionView.displayName = 'Expression';
ExpressionView.propTypes = {
  context: _propTypes["default"].object,
  dataSource: _propTypes["default"].array,
  locale: _propTypes["default"].string,
  messages: _propTypes["default"].object,
  onChange: _propTypes["default"].func,
  placeholder: _propTypes["default"].string,
  value: _propTypes["default"].string
};
ExpressionView.defaultProps = {
  context: {},
  dataSource: [],
  locale: 'zh-CN',
  messages: _zhCN["default"],
  onChange: function onChange() {},
  placeholder: '',
  value: ''
};