"use strict";

var _typeof3 = require("@babel/runtime-corejs3/helpers/typeof");

var _WeakMap = require("@babel/runtime-corejs3/core-js-stable/weak-map");

var _Object$getOwnPropertyDescriptor = require("@babel/runtime-corejs3/core-js-stable/object/get-own-property-descriptor");

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

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.getSortData = getSortData;
exports["default"] = useFilterSorter;

var _concat = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/concat"));

var _map = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/map"));

var _find = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/find"));

var _includes = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/includes"));

var _filter = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/filter"));

var _sort = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/sort"));

var _slice = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/slice"));

var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/slicedToArray"));

var _defineProperty2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/defineProperty"));

var _extends3 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/extends"));

var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/toConsumableArray"));

var _typeof2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/typeof"));

var React = _interopRequireWildcard(require("react"));

var _classnames = _interopRequireDefault(require("classnames"));

var _CaretDownOutlined = _interopRequireDefault(require("mk-icon/lib/icons/CaretDownOutlined"));

var _CaretUpOutlined = _interopRequireDefault(require("mk-icon/lib/icons/CaretUpOutlined"));

var _tooltip = _interopRequireDefault(require("../../tooltip"));

var _util = require("../util");

function _getRequireWildcardCache(nodeInterop) { if (typeof _WeakMap !== "function") return null; var cacheBabelInterop = new _WeakMap(); var cacheNodeInterop = new _WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }

function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof3(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && _Object$getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? _Object$getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }

var ASCEND = 'ascend';
var DESCEND = 'descend';

function getMultiplePriority(column) {
  if ((0, _typeof2["default"])(column.sorter) === 'object' && typeof column.sorter.multiple === 'number') {
    return column.sorter.multiple;
  }

  return false;
}

function getSortFunction(sorter) {
  if (typeof sorter === 'function') {
    return sorter;
  }

  if (sorter && (0, _typeof2["default"])(sorter) === 'object' && sorter.compare) {
    return sorter.compare;
  }

  return false;
}

function nextSortDirection(sortDirections, current) {
  if (!current) {
    return sortDirections[0];
  }

  return sortDirections[sortDirections.indexOf(current) + 1];
}

function collectSortStates(columns, init, pos) {
  var sortStates = [];

  function pushState(column, columnPos) {
    sortStates.push({
      column: column,
      key: (0, _util.getColumnKey)(column, columnPos),
      multiplePriority: getMultiplePriority(column),
      sortOrder: column.sortOrder
    });
  }

  (columns || []).forEach(function (column, index) {
    var columnPos = (0, _util.getColumnPos)(index, pos);

    if (column.children) {
      var _context;

      if ('sortOrder' in column) {
        // Controlled
        pushState(column, columnPos);
      }

      sortStates = (0, _concat["default"])(_context = []).call(_context, (0, _toConsumableArray2["default"])(sortStates), (0, _toConsumableArray2["default"])(collectSortStates(column.children, init, columnPos)));
    } else if (column.sorter) {
      if ('sortOrder' in column) {
        // Controlled
        pushState(column, columnPos);
      } else if (init && column.defaultSortOrder) {
        // Default sorter
        sortStates.push({
          column: column,
          key: (0, _util.getColumnKey)(column, columnPos),
          multiplePriority: getMultiplePriority(column),
          sortOrder: column.defaultSortOrder
        });
      }
    }
  });
  return sortStates;
}

function injectSorter(prefixCls, columns, sorterSates, triggerSorter, defaultSortDirections, tableLocale, tableShowSorterTooltip, pos) {
  var _context2;

  return (0, _map["default"])(_context2 = columns || []).call(_context2, function (column, index) {
    var columnPos = (0, _util.getColumnPos)(index, pos);
    var newColumn = column;

    if (newColumn.sorter) {
      var sortDirections = newColumn.sortDirections || defaultSortDirections;
      var showSorterTooltip = newColumn.showSorterTooltip === undefined ? tableShowSorterTooltip : newColumn.showSorterTooltip;
      var columnKey = (0, _util.getColumnKey)(newColumn, columnPos);
      var sorterState = (0, _find["default"])(sorterSates).call(sorterSates, function (_ref) {
        var key = _ref.key;
        return key === columnKey;
      });
      var sorterOrder = sorterState ? sorterState.sortOrder : null;
      var nextSortOrder = nextSortDirection(sortDirections, sorterOrder);
      var upNode = (0, _includes["default"])(sortDirections).call(sortDirections, ASCEND) && /*#__PURE__*/React.createElement(_CaretUpOutlined["default"], {
        className: (0, _classnames["default"])("".concat(prefixCls, "-column-sorter-up"), {
          active: sorterOrder === ASCEND
        })
      });
      var downNode = (0, _includes["default"])(sortDirections).call(sortDirections, DESCEND) && /*#__PURE__*/React.createElement(_CaretDownOutlined["default"], {
        className: (0, _classnames["default"])("".concat(prefixCls, "-column-sorter-down"), {
          active: sorterOrder === DESCEND
        })
      });

      var _ref2 = tableLocale || {},
          cancelSort = _ref2.cancelSort,
          triggerAsc = _ref2.triggerAsc,
          triggerDesc = _ref2.triggerDesc;

      var sortTip = cancelSort;

      if (nextSortOrder === DESCEND) {
        sortTip = triggerDesc;
      } else if (nextSortOrder === ASCEND) {
        sortTip = triggerAsc;
      }

      newColumn = (0, _extends3["default"])((0, _extends3["default"])({}, newColumn), {
        className: (0, _classnames["default"])(newColumn.className, (0, _defineProperty2["default"])({}, "".concat(prefixCls, "-column-sort"), sorterOrder)),
        title: function title(renderProps) {
          var renderSortTitle = /*#__PURE__*/React.createElement("div", {
            className: "".concat(prefixCls, "-column-sorters")
          }, /*#__PURE__*/React.createElement("span", null, (0, _util.renderColumnTitle)(column.title, renderProps)), /*#__PURE__*/React.createElement("span", {
            className: (0, _classnames["default"])("".concat(prefixCls, "-column-sorter"), (0, _defineProperty2["default"])({}, "".concat(prefixCls, "-column-sorter-full"), upNode && downNode))
          }, /*#__PURE__*/React.createElement("span", {
            className: "".concat(prefixCls, "-column-sorter-inner")
          }, upNode, downNode)));
          return showSorterTooltip ? /*#__PURE__*/React.createElement(_tooltip["default"], {
            title: sortTip
          }, /*#__PURE__*/React.createElement("div", {
            className: "".concat(prefixCls, "-column-sorters-with-tooltip")
          }, renderSortTitle)) : renderSortTitle;
        },
        onHeaderCell: function onHeaderCell(col) {
          var cell = column.onHeaderCell && column.onHeaderCell(col) || {};
          var originOnClick = cell.onClick;

          cell.onClick = function (event) {
            triggerSorter({
              column: column,
              key: columnKey,
              sortOrder: nextSortOrder,
              multiplePriority: getMultiplePriority(column)
            });

            if (originOnClick) {
              originOnClick(event);
            }
          };

          cell.className = (0, _classnames["default"])(cell.className, "".concat(prefixCls, "-column-has-sorters"));
          return cell;
        }
      });
    }

    if ('children' in newColumn) {
      newColumn = (0, _extends3["default"])((0, _extends3["default"])({}, newColumn), {
        children: injectSorter(prefixCls, newColumn.children, sorterSates, triggerSorter, defaultSortDirections, tableLocale, tableShowSorterTooltip, columnPos)
      });
    }

    return newColumn;
  });
}

function stateToInfo(sorterStates) {
  var column = sorterStates.column,
      sortOrder = sorterStates.sortOrder;
  return {
    column: column,
    order: sortOrder,
    field: column.dataIndex,
    columnKey: column.key
  };
}

function generateSorterInfo(sorterStates) {
  var _context3;

  var list = (0, _map["default"])(_context3 = (0, _filter["default"])(sorterStates).call(sorterStates, function (_ref3) {
    var sortOrder = _ref3.sortOrder;
    return sortOrder;
  })).call(_context3, stateToInfo); // =========== Legacy compatible support ===========
  // https://github.com/ant-design/ant-design/pull/19226

  if (list.length === 0 && sorterStates.length) {
    return (0, _extends3["default"])((0, _extends3["default"])({}, stateToInfo(sorterStates[sorterStates.length - 1])), {
      column: undefined
    });
  }

  if (list.length <= 1) {
    return list[0] || {};
  }

  return list;
}

function getSortData(data, sortStates, childrenColumnName) {
  var _context4, _context5;

  var innerSorterStates = (0, _sort["default"])(_context4 = (0, _slice["default"])(sortStates).call(sortStates)).call(_context4, function (a, b) {
    return b.multiplePriority - a.multiplePriority;
  });
  var cloneData = (0, _slice["default"])(data).call(data);
  var runningSorters = (0, _filter["default"])(innerSorterStates).call(innerSorterStates, function (_ref4) {
    var sorter = _ref4.column.sorter,
        sortOrder = _ref4.sortOrder;
    return getSortFunction(sorter) && sortOrder;
  }); // Skip if no sorter needed

  if (!runningSorters.length) {
    return cloneData;
  }

  return (0, _map["default"])(_context5 = (0, _sort["default"])(cloneData).call(cloneData, function (record1, record2) {
    for (var i = 0; i < runningSorters.length; i += 1) {
      var sorterState = runningSorters[i];
      var sorter = sorterState.column.sorter,
          sortOrder = sorterState.sortOrder;
      var compareFn = getSortFunction(sorter);

      if (compareFn && sortOrder) {
        var compareResult = compareFn(record1, record2, sortOrder);

        if (compareResult !== 0) {
          return sortOrder === ASCEND ? compareResult : -compareResult;
        }
      }
    }

    return 0;
  })).call(_context5, function (record) {
    var subRecords = record[childrenColumnName];

    if (subRecords) {
      return (0, _extends3["default"])((0, _extends3["default"])({}, record), (0, _defineProperty2["default"])({}, childrenColumnName, getSortData(subRecords, sortStates, childrenColumnName)));
    }

    return record;
  });
}

function useFilterSorter(_ref5) {
  var prefixCls = _ref5.prefixCls,
      mergedColumns = _ref5.mergedColumns,
      onSorterChange = _ref5.onSorterChange,
      sortDirections = _ref5.sortDirections,
      tableLocale = _ref5.tableLocale,
      showSorterTooltip = _ref5.showSorterTooltip;

  var _React$useState = React.useState(collectSortStates(mergedColumns, true)),
      _React$useState2 = (0, _slicedToArray2["default"])(_React$useState, 2),
      sortStates = _React$useState2[0],
      setSortStates = _React$useState2[1];

  var mergedSorterStates = React.useMemo(function () {
    var validate = true;
    var collectedStates = collectSortStates(mergedColumns, false); // Return if not controlled

    if (!collectedStates.length) {
      return sortStates;
    }

    var validateStates = [];

    function patchStates(state) {
      if (validate) {
        validateStates.push(state);
      } else {
        validateStates.push((0, _extends3["default"])((0, _extends3["default"])({}, state), {
          sortOrder: null
        }));
      }
    }

    var multipleMode = null;
    collectedStates.forEach(function (state) {
      if (multipleMode === null) {
        patchStates(state);

        if (state.sortOrder) {
          if (state.multiplePriority === false) {
            validate = false;
          } else {
            multipleMode = true;
          }
        }
      } else if (multipleMode && state.multiplePriority !== false) {
        patchStates(state);
      } else {
        validate = false;
        patchStates(state);
      }
    });
    return validateStates;
  }, [mergedColumns, sortStates]); // Get render columns title required props

  var columnTitleSorterProps = React.useMemo(function () {
    var sortColumns = (0, _map["default"])(mergedSorterStates).call(mergedSorterStates, function (_ref6) {
      var column = _ref6.column,
          sortOrder = _ref6.sortOrder;
      return {
        column: column,
        order: sortOrder
      };
    });
    return {
      sortColumns: sortColumns,
      // Legacy
      sortColumn: sortColumns[0] && sortColumns[0].column,
      sortOrder: sortColumns[0] && sortColumns[0].order
    };
  }, [mergedSorterStates]);

  function triggerSorter(sortState) {
    var newSorterStates;

    if (sortState.multiplePriority === false || !mergedSorterStates.length || mergedSorterStates[0].multiplePriority === false) {
      newSorterStates = [sortState];
    } else {
      var _context6;

      newSorterStates = (0, _concat["default"])(_context6 = []).call(_context6, (0, _toConsumableArray2["default"])((0, _filter["default"])(mergedSorterStates).call(mergedSorterStates, function (_ref7) {
        var key = _ref7.key;
        return key !== sortState.key;
      })), [sortState]);
    }

    setSortStates(newSorterStates);
    onSorterChange(generateSorterInfo(newSorterStates), newSorterStates);
  }

  var transformColumns = function transformColumns(innerColumns) {
    return injectSorter(prefixCls, innerColumns, mergedSorterStates, triggerSorter, sortDirections, tableLocale, showSorterTooltip);
  };

  var getSorters = function getSorters() {
    return generateSorterInfo(mergedSorterStates);
  };

  return [transformColumns, mergedSorterStates, columnTitleSorterProps, getSorters];
}