"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");

exports.__esModule = true;
exports.getColumnsAndPaths = getColumnsAndPaths;
exports.usePaths = usePaths;

var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));

var _react = require("react");

var _slice = _interopRequireDefault(require("lodash/slice"));

var _utils = require("../utils");

var _treeUtils = require("../utils/treeUtils");

function getColumnsAndPaths(data, value, options) {
  var childrenKey = options.childrenKey,
      valueKey = options.valueKey,
      isAttachChildren = options.isAttachChildren;
  var columns = [];
  var paths = [];

  var findNode = function findNode(items) {
    var _loop = function _loop(i) {
      var children = items[i][childrenKey];

      if ((0, _utils.shallowEqual)(items[i][valueKey], value)) {
        return {
          v: {
            items: items,
            active: items[i]
          }
        };
      } else if (children) {
        var node = findNode(children);

        if (node) {
          columns.push(children.map(function (item) {
            return (0, _extends2.default)({}, item, {
              parent: items[i]
            });
          }));
          paths.push(node.active);
          return {
            v: {
              items: items,
              active: items[i]
            }
          };
        }
      }
    };

    for (var i = 0; i < items.length; i += 1) {
      var _ret = _loop(i);

      if (typeof _ret === "object") return _ret.v;
    }

    return null;
  };

  var selectedNode = findNode(data);
  columns.push(data);

  if (selectedNode) {
    paths.push(selectedNode.active);
  }

  if (isAttachChildren) {
    var valueToNode = (0, _treeUtils.findNodeOfTree)(data, function (item) {
      return item[valueKey] === value;
    });

    if (valueToNode === null || valueToNode === void 0 ? void 0 : valueToNode[childrenKey]) {
      columns.unshift(valueToNode[childrenKey]);
    }
  }

  columns.reverse();
  paths.reverse();
  return {
    columns: columns,
    paths: paths
  };
}

function usePaths(props) {
  var data = props.data,
      valueKey = props.valueKey,
      childrenKey = props.childrenKey,
      value = props.value;

  var _useMemo = (0, _react.useMemo)(function () {
    return getColumnsAndPaths(data, value, {
      valueKey: valueKey,
      childrenKey: childrenKey
    });
  }, [data, value, valueKey, childrenKey]),
      columns = _useMemo.columns,
      paths = _useMemo.paths; // The columns displayed in the cascading panel.


  var _useState = (0, _react.useState)(columns),
      columnData = _useState[0],
      setColumnData = _useState[1]; // The path after cascading data selection.


  var _useState2 = (0, _react.useState)(paths),
      selectedPaths = _useState2[0],
      setSelectedPaths = _useState2[1]; // The path corresponding to the selected value.


  var _useState3 = (0, _react.useState)(paths),
      valueToPaths = _useState3[0],
      setValueToPaths = _useState3[1];
  /**
   * Add a list of options to the cascading panel. Used for lazy loading options.
   * @param column
   * @param index The index of the current column.
   */


  function addColumn(column, index) {
    setColumnData([].concat((0, _slice.default)(columnData, 0, index), [column]));
  }
  /**
   * Enforce update of columns and paths.
   * @param nextValue  Selected value
   * @param isAttachChildren  Whether to attach the children of the selected node.
   */


  function enforceUpdate(nextValue, isAttachChildren) {
    var _getColumnsAndPaths = getColumnsAndPaths(data, nextValue, {
      valueKey: valueKey,
      childrenKey: childrenKey,
      isAttachChildren: isAttachChildren
    }),
        columns = _getColumnsAndPaths.columns,
        paths = _getColumnsAndPaths.paths;

    setColumnData(columns);
    setSelectedPaths(paths);
  }

  (0, _utils.useUpdateEffect)(function () {
    // Update paths when value is updated, then update valueToPaths.
    setValueToPaths(paths);
  }, [paths]);
  (0, _utils.useUpdateEffect)(function () {
    enforceUpdate(value);
  }, [data]);
  return {
    enforceUpdate: enforceUpdate,
    columnData: columnData,
    valueToPaths: valueToPaths,
    selectedPaths: selectedPaths,
    setValueToPaths: setValueToPaths,
    setColumnData: setColumnData,
    setSelectedPaths: setSelectedPaths,
    addColumn: addColumn
  };
}