import _regeneratorRuntime from 'babel-runtime/regenerator';

var _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; };

function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }

function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; }

// require PrototypeArray.js(flattenTree)
import React, { forwardRef, useRef, useImperativeHandle, useEffect } from 'react';
import Instance from './instance.js';

var Tree = forwardRef(function (_ref, ref) {

  // 异步加载的方法, 点击Title, 去请求数据, 将数据塞到指定节点下
  var addChildren = function () {
    var _ref5 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(s, item, isActived, isExtend, childrenCount) {
      var ul, leaf;
      return _regeneratorRuntime.wrap(function _callee$(_context) {
        while (1) {
          switch (_context.prev = _context.next) {
            case 0:
              if (!(!isExtend || s.targetLine.childrenLoaded)) {
                _context.next = 2;
                break;
              }

              return _context.abrupt('return');

            case 2:
              ul = s.targetLine.nextElementSibling;
              _context.next = 5;
              return getChildren(item.id);

            case 5:
              leaf = _context.sent;

              if (!(leaf instanceof Array === false)) {
                _context.next = 8;
                break;
              }

              return _context.abrupt('return');

            case 8:
              instance.current.addData(leaf, item.id, ul);
              if (s.targetLine) s.targetLine.childrenLoaded = true;

            case 10:
            case 'end':
              return _context.stop();
          }
        }
      }, _callee, this);
    }));

    return function addChildren(_x, _x2, _x3, _x4, _x5) {
      return _ref5.apply(this, arguments);
    };
  }();

  var _ref$split = _ref.split,
      split = _ref$split === undefined ? ',' : _ref$split,
      _ref$multiple = _ref.multiple,
      multiple = _ref$multiple === undefined ? false : _ref$multiple,
      _ref$checkbox = _ref.checkbox,
      checkbox = _ref$checkbox === undefined ? true : _ref$checkbox,
      _ref$arrowAutoShow = _ref.arrowAutoShow,
      arrowAutoShow = _ref$arrowAutoShow === undefined ? false : _ref$arrowAutoShow,
      _ref$extend = _ref.extend,
      extend = _ref$extend === undefined ? 0 : _ref$extend,
      bar = _ref.bar,
      _ref$treeAttribute = _ref.treeAttribute,
      treeAttribute = _ref$treeAttribute === undefined ? {} : _ref$treeAttribute,
      _ref$buttonAddAttribu = _ref.buttonAddAttribute,
      buttonAddAttribute = _ref$buttonAddAttribu === undefined ? {} : _ref$buttonAddAttribu,
      _ref$buttonDelAttribu = _ref.buttonDelAttribute,
      buttonDelAttribute = _ref$buttonDelAttribu === undefined ? {} : _ref$buttonDelAttribu,
      _ref$selected = _ref.selected,
      selected = _ref$selected === undefined ? [] : _ref$selected,
      _ref$selectedAutoClea = _ref.selectedAutoClear,
      selectedAutoClear = _ref$selectedAutoClea === undefined ? false : _ref$selectedAutoClea,
      _ref$list = _ref.list,
      list = _ref$list === undefined ? [] : _ref$list,
      getChildren = _ref.getChildren,
      onChange = _ref.onChange,
      onClick = _ref.onClick,
      onClickLeaf = _ref.onClickLeaf,
      onData = _ref.onData,
      _ref$params = _ref.params,
      params = _ref$params === undefined ? {} : _ref$params,
      others = _objectWithoutProperties(_ref, ['split', 'multiple', 'checkbox', 'arrowAutoShow', 'extend', 'bar', 'treeAttribute', 'buttonAddAttribute', 'buttonDelAttribute', 'selected', 'selectedAutoClear', 'list', 'getChildren', 'onChange', 'onClick', 'onClickLeaf', 'onData', 'params']);

  var refEl = useRef(null);
  useImperativeHandle(ref, function () {
    return refEl.current;
  });
  var instance = useRef(null);

  useEffect(function () {
    if (instance.current) return;
    // 更新数据
    var data = Object.clone(list);
    if (JSON.stringify(data).indexOf('"children"') !== -1) {
      data = data.flattenTree();
    }
    var elTree = refEl.current.querySelector('ul');
    console.log('初始化, 是否多选:' + multiple);
    instance.current = new Instance(elTree, _extends({
      data: data,
      selectedAutoClear: selectedAutoClear,
      multiple: multiple,
      checkbox: checkbox,
      arrowAutoShow: arrowAutoShow,
      bar: bar,
      buttonAddClass: buttonAddAttribute.className,
      onClickAdd: buttonAddAttribute.onClick,
      buttonDelClass: buttonDelAttribute.className,
      onClickDel: buttonDelAttribute.onClick,
      onClick: click,
      onChange: change,
      onData: onData
    }, params || {}));
    // 渲染数据
    instance.current.update();
    // 设置已选中
    checkedSelected();
    refEl.current.instance = instance;
  }, []); // eslint-disable-line

  useEffect(function () {
    if (extend === 1) {
      instance.current.extendAll();
    } else if (extend === -1) {
      instance.current.collapseAll();
    }
  }, [extend]);

  useEffect(function () {
    if (!instance.current) return;
    if (list && list.length) {
      var data = Object.clone(list);
      if (JSON.stringify(data).indexOf('"children"') !== -1) {
        data = data.flattenTree();
      }
      // 选中选中项
      checkedSelected();
      // 开始渲染
      instance.current.setData(data);
      instance.current.update();
    } else {
      instance.current.setData([]);
      instance.current.update();
    }
  }, [list]); // eslint-disable-line

  useEffect(function () {
    if (!bar || !instance.current) return;
    instance.current.params.bar = bar;
    instance.current.updateBar();
    barSelected();
  }, [bar]); // eslint-disable-line

  // 更新句柄, 防止synchronization模式, 每次组件在render的时候都生成上次render的state、function、effects
  if (instance.current) {
    instance.current.params.onClick = click;
    instance.current.params.onChange = change;
    instance.current.params.onData = onData;
  }

  // 选中选中项
  function checkedSelected() {
    if (selected && selected.length) {
      for (var _iterator = selected, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
        var _ref2;

        if (_isArray) {
          if (_i >= _iterator.length) break;
          _ref2 = _iterator[_i++];
        } else {
          _i = _iterator.next();
          if (_i.done) break;
          _ref2 = _i.value;
        }

        var item = _ref2;

        instance.current.addSelected(item);
      }
    } else {
      instance.current.removeAllSelected();
    }
  }
  // 当bar更新时, 选中项放到bar上
  function barSelected() {
    instance.current.bar.innerHTML = '';
    if (selected && selected.length) {
      for (var _iterator2 = selected, _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) {
        var _ref3;

        if (_isArray2) {
          if (_i2 >= _iterator2.length) break;
          _ref3 = _iterator2[_i2++];
        } else {
          _i2 = _iterator2.next();
          if (_i2.done) break;
          _ref3 = _i2.value;
        }

        var item = _ref3;

        instance.current.addBarOption(item);
      }
    } else {
      instance.current.removeAllSelected();
    }
  }

  // 选中项
  function change(s) {
    if (refEl.current) s.target = refEl.current;
    if (onChange) {
      var value = [];
      for (var id in s.selected) {
        value.push(s.selected[id].name);
      }
      onChange(s, value.join(','), Object.values(s.selected));
    }
  }

  // 判断是否选中
  function isSelected(id) {
    if (!Array.isArray(selected) || !id) return false;
    for (var _iterator3 = selected, _isArray3 = Array.isArray(_iterator3), _i3 = 0, _iterator3 = _isArray3 ? _iterator3 : _iterator3[Symbol.iterator]();;) {
      var _ref4;

      if (_isArray3) {
        if (_i3 >= _iterator3.length) break;
        _ref4 = _iterator3[_i3++];
      } else {
        _i3 = _iterator3.next();
        if (_i3.done) break;
        _ref4 = _i3.value;
      }

      var item = _ref4;

      if (item.id === id) return true;
    }
    return false;
  }

  // 点击
  function click(s) {
    if (!s.targetLine) return;
    if (refEl.current) s.target = refEl.current;
    var data = Object.clone(list);
    if (JSON.stringify(data).indexOf('"children"') !== -1) {
      data = data.flattenTree();
    }
    // item
    var id = s.targetLine.getAttribute('data-id');
    var item = data.getFlattenTreeNode(id);
    // isActived
    var isActived = isSelected(id) ? true : false;
    // childrenCount
    var childrenCount = 0;
    var ul = s.targetLine.nextElementSibling;
    if (ul && ul.tagName === 'UL') {
      childrenCount = ul.children.length;
    }
    // isExtend
    var isExtend = s.targetLine.classList.contains('extend');

    // 点击回调
    if (onClick) onClick(s, item.name, item, isActived, isExtend, childrenCount);
    if (s.isLeaf && onClickLeaf) onClickLeaf(s, item.name, item, isActived);

    if (getChildren) {
      addChildren(s, item, isActived, isExtend, childrenCount);
    }
  }

  return React.createElement(
    'div',
    _extends({ ref: refEl }, others, { className: 'tree-box' + (others.className ? ' ' + others.className : '') }),
    React.createElement('ul', _extends({}, treeAttribute, { className: 'tree' + (multiple ? '' : ' tree-type-radio') + (treeAttribute.className ? ' ' + treeAttribute.className : '') }))
  );
});

export default Tree;