import "choerodon-ui/pro/lib/button/style";
import _Button from "choerodon-ui/pro/lib/button";
import "choerodon-ui/pro/lib/form/style";
import _Form from "@hzero-front-ui/c7n-ui/lib/FormPro";
import "choerodon-ui/pro/lib/select/style";
import _Select from "choerodon-ui/pro/lib/select";

var _this = this;

function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }

function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }

function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }

function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }

function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }

function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }

function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }

function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }

function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }

function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }

function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure 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; }

function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }

function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }

/* eslint-disable max-len */
import React, { useEffect, useState, useMemo } from 'react';
import { injectIntl } from 'react-intl';
import { observer } from 'mobx-react-lite';
import { forEach, map, debounce, some } from 'lodash';
import useStore from "./stores/useStore";
import "./index.less";
var DynamicSelect = injectIntl(observer(function (props) {
  var formatMessage = props.intl.formatMessage,
      selectDataSet = props.selectDataSet,
      optionsFilter = props.optionsFilter,
      optionsRenderer = props.optionsRenderer,
      optionsDataSet = props.optionsDataSet,
      addText = props.addText,
      selectName = props.selectName,
      loadMore = props.loadMore,
      renderer = props.renderer,
      _props$optionKeyName = props.optionKeyName,
      optionKeyName = _props$optionKeyName === void 0 ? selectName : _props$optionKeyName;
  var selectField = selectDataSet.getField(selectName);
  var valueField = selectField.get('valueField');
  var textField = selectField.get('textField');
  var store = useStore();

  var _useState = useState(null),
      _useState2 = _slicedToArray(_useState, 2),
      searchParam = _useState2[0],
      setSearchParam = _useState2[1];

  useEffect(function () {
    selectDataSet.getField(selectName).set('options', optionsDataSet);
    selectDataSet.create();
    loadInitData();
    return function () {
      selectDataSet.reset();
    };
  }, []);

  function handleDelete(current) {
    selectDataSet.remove(current);
  }

  function handleCreate() {
    selectDataSet.create();
  }

  function loadData() {
    return _loadData.apply(this, arguments);
  }

  function _loadData() {
    _loadData = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee() {
      var searchPage,
          res,
          tempMap,
          item,
          _optionsDataSet$creat,
          loadMoreRecord,
          _args = arguments;

      return regeneratorRuntime.wrap(function _callee$(_context) {
        while (1) {
          switch (_context.prev = _context.next) {
            case 0:
              searchPage = _args.length > 0 && _args[0] !== undefined ? _args[0] : 1;
              _context.t0 = optionsDataSet;

              if (!_context.t0) {
                _context.next = 6;
                break;
              }

              _context.next = 5;
              return optionsDataSet.query(searchPage);

            case 5:
              _context.t0 = _context.sent;

            case 6:
              res = _context.t0;

              if (!(res && !res.failed)) {
                _context.next = 18;
                break;
              }

              // 将记录以 id=>record的形式缓存起来，方便做map的快速查询
              tempMap = {};
              forEach(optionsDataSet.data, function (r) {
                tempMap[r.get(valueField)] = r;
              }); // 将已选中的数据拼接到现有数据 optionMap是上次的缓存数据，tempMap是本次的数据
              // 如果选中的数据已经在此次获取到的数据里，不做拼接操作

              forEach(selectDataSet.data, function (r) {
                var value = r.get(selectName);

                if (store.optionMap[value] && !tempMap[value]) {
                  optionsDataSet.push(store.optionMap[value]);
                }
              });
              store.setOptionMap(_objectSpread(_objectSpread({}, store.optionMap), tempMap));

              if (!res.isFirstPage && res.list && res.list.length) {
                optionsDataSet.unshift.apply(optionsDataSet, _toConsumableArray(store.oldOptionsData));
              }

              item = optionsDataSet.find(function (r) {
                return r.get(optionKeyName) === 'More';
              });
              item && optionsDataSet.remove(item);
              store.setOldOptionsData(optionsDataSet.records); // 手动加入加载更多的选项

              if (res.hasNextPage) {
                loadMoreRecord = optionsDataSet.create((_optionsDataSet$creat = {}, _defineProperty(_optionsDataSet$creat, valueField, 'More'), _defineProperty(_optionsDataSet$creat, textField, 'More'), _optionsDataSet$creat));
                optionsDataSet.push(loadMoreRecord);
              }

              return _context.abrupt("return", res);

            case 18:
              return _context.abrupt("return", false);

            case 19:
            case "end":
              return _context.stop();
          }
        }
      }, _callee);
    }));
    return _loadData.apply(this, arguments);
  }

  function setQueryParameter(param) {
    if (optionsDataSet) {
      optionsDataSet.transport.read.data = {
        params: param ? [param] : [],
        searchParam: {}
      };
    }
  }

  function loadInitData() {
    searchParam && setQueryParameter(searchParam);
    return loadData();
  }

  var searchData = useMemo(function () {
    return debounce(function (value) {
      setQueryParameter(value);

      if (value) {
        loadData();
      } else {
        loadInitData();
      }
    }, 500);
  }, []);

  function loadMoreWrap(e) {
    e.stopPropagation();

    if (loadMore) {
      loadMore();
    } else {
      loadData(optionsDataSet.currentPage + 1);
    }
  }

  function handleInput(e) {
    e.persist();
    setSearchParam(e.target.value);
    searchData(e.target.value);
  }

  function handleBlur() {
    if (optionsDataSet) {
      optionsDataSet.transport.read.data = null;
    }

    loadData();
  }

  function optionRendererWraper(_ref) {
    var record = _ref.record,
        text = _ref.text,
        value = _ref.value;

    if (text === value && value === 'More') {
      return /*#__PURE__*/React.createElement("div", {
        onClick: loadMoreWrap.bind(this),
        className: "c7n-option-popover",
        role: "none"
      }, /*#__PURE__*/React.createElement("span", {
        className: "c7n-option-span"
      }, formatMessage({
        id: 'loadMore'
      })));
    }

    if (!renderer) return text;
    return optionsRenderer({
      record: record,
      text: text,
      value: value
    });
  }

  function rendererWraper(_ref2) {
    var record = _ref2.record,
        text = _ref2.text,
        value = _ref2.value;
    if (!value || !store.optionMap[value]) return;
    if (!renderer) return text;
    return /*#__PURE__*/React.createElement("div", {
      className: "renderer-wraper"
    }, renderer({
      valueRecord: record,
      text: text,
      value: value,
      optionRecord: store.optionMap[value]
    }));
  }

  function optionsFilterWaper(record) {
    if (record.get(valueField) === 'More') return true;
    if (optionsFilter) return optionsFilter(record);
    var flag = some(selectDataSet.created, function (r) {
      return r.get(selectName) === record.get(optionKeyName);
    });
    return !flag;
  }

  return /*#__PURE__*/React.createElement("div", {
    className: "dynamic-select-form"
  }, map(selectDataSet.created, function (createdRecord, index) {
    return /*#__PURE__*/React.createElement("div", {
      className: "dynamic-select-form-item",
      key: "dynamic-select-form-".concat(index)
    }, /*#__PURE__*/React.createElement(_Form, {
      record: createdRecord
    }, /*#__PURE__*/React.createElement(_Select, {
      name: selectName,
      optionRenderer: optionRendererWraper,
      renderer: rendererWraper,
      optionsFilter: optionsFilterWaper,
      searchable: true,
      onInput: handleInput,
      searchMatcher: function searchMatcher() {
        return true;
      },
      onBlur: handleBlur.bind(_this, createdRecord),
      popupCls: "c7ncd-select-menu-item-more-hidden"
    })), /*#__PURE__*/React.createElement(_Button, {
      icon: "delete",
      shape: "circle",
      funcType: "flat",
      onClick: function onClick() {
        return handleDelete(createdRecord);
      },
      disabled: selectDataSet.created.length === 1,
      className: "dynamic-select-form-button"
    }));
  }), /*#__PURE__*/React.createElement(_Button, {
    icon: "add",
    color: "primary",
    funcType: "flat",
    onClick: handleCreate
  }, addText));
}));
export default DynamicSelect;