import _slicedToArray from "@babel/runtime-corejs3/helpers/slicedToArray";
import _defineProperty from "@babel/runtime-corejs3/helpers/defineProperty";
import _extends from "@babel/runtime-corejs3/helpers/extends";
import _toConsumableArray from "@babel/runtime-corejs3/helpers/toConsumableArray";
import _typeof from "@babel/runtime-corejs3/helpers/typeof";
import _concatInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/concat";
import _mapInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/map";
import _findInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/find";
import _includesInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/includes";
import _filterInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/filter";
import _sortInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/sort";
import _sliceInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/slice";
import * as React from 'react';
import classNames from 'classnames';
import CaretDownOutlined from "mk-icon/es/icons/CaretDownOutlined";
import CaretUpOutlined from "mk-icon/es/icons/CaretUpOutlined";
import Tooltip from '../../tooltip';
import { getColumnKey, getColumnPos, renderColumnTitle } from '../util';
var ASCEND = 'ascend';
var DESCEND = 'descend';

function getMultiplePriority(column) {
  if (_typeof(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 && _typeof(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: getColumnKey(column, columnPos),
      multiplePriority: getMultiplePriority(column),
      sortOrder: column.sortOrder
    });
  }

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

    if (column.children) {
      var _context;

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

      sortStates = _concatInstanceProperty(_context = []).call(_context, _toConsumableArray(sortStates), _toConsumableArray(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: getColumnKey(column, columnPos),
          multiplePriority: getMultiplePriority(column),
          sortOrder: column.defaultSortOrder
        });
      }
    }
  });
  return sortStates;
}

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

  return _mapInstanceProperty(_context2 = columns || []).call(_context2, function (column, index) {
    var columnPos = getColumnPos(index, pos);
    var newColumn = column;

    if (newColumn.sorter) {
      var sortDirections = newColumn.sortDirections || defaultSortDirections;
      var showSorterTooltip = newColumn.showSorterTooltip === undefined ? tableShowSorterTooltip : newColumn.showSorterTooltip;
      var columnKey = getColumnKey(newColumn, columnPos);

      var sorterState = _findInstanceProperty(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 = _includesInstanceProperty(sortDirections).call(sortDirections, ASCEND) && /*#__PURE__*/React.createElement(CaretUpOutlined, {
        className: classNames("".concat(prefixCls, "-column-sorter-up"), {
          active: sorterOrder === ASCEND
        })
      });
      var downNode = _includesInstanceProperty(sortDirections).call(sortDirections, DESCEND) && /*#__PURE__*/React.createElement(CaretDownOutlined, {
        className: classNames("".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 = _extends(_extends({}, newColumn), {
        className: classNames(newColumn.className, _defineProperty({}, "".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, renderColumnTitle(column.title, renderProps)), /*#__PURE__*/React.createElement("span", {
            className: classNames("".concat(prefixCls, "-column-sorter"), _defineProperty({}, "".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, {
            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 = classNames(cell.className, "".concat(prefixCls, "-column-has-sorters"));
          return cell;
        }
      });
    }

    if ('children' in newColumn) {
      newColumn = _extends(_extends({}, 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 = _mapInstanceProperty(_context3 = _filterInstanceProperty(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 _extends(_extends({}, stateToInfo(sorterStates[sorterStates.length - 1])), {
      column: undefined
    });
  }

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

  return list;
}

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

  var innerSorterStates = _sortInstanceProperty(_context4 = _sliceInstanceProperty(sortStates).call(sortStates)).call(_context4, function (a, b) {
    return b.multiplePriority - a.multiplePriority;
  });

  var cloneData = _sliceInstanceProperty(data).call(data);

  var runningSorters = _filterInstanceProperty(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 _mapInstanceProperty(_context5 = _sortInstanceProperty(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 _extends(_extends({}, record), _defineProperty({}, childrenColumnName, getSortData(subRecords, sortStates, childrenColumnName)));
    }

    return record;
  });
}
export default 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 = _slicedToArray(_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(_extends(_extends({}, 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 = _mapInstanceProperty(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 = _concatInstanceProperty(_context6 = []).call(_context6, _toConsumableArray(_filterInstanceProperty(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];
}