/**
 * O dragElement é posicionado ANTERIORMENTE ao targetIndex.
 * Ex: no array: ["A", "B", "C", "D", "E"]
 * se o dragItem for "B" e o targetIndex 3 (referente à "D"),
 * "B" será posicionado logo antes de "D".
 * O resultado será: ["A", "C", "B", "D", "E"]
 *
 * @param configs
 */
export function processListOnDrop(configs) {
  let newList;
  if (hasToMoveMultipleItems(configs)) {
    newList = processMoveMultipleItems(configs);
  }
  else {
    newList = processMoveSingleItem(configs);
    configs.clearSelection();
  }
  return newList;
}
function hasToMoveMultipleItems(configs) {
  const { enableMultipleSelection, listItems, dragItem, moveToFinal, targetIndex } = configs;
  if (!enableMultipleSelection)
    return false;
  const selectedItemsIndexes = getSelectedIndices(listItems);
  if (selectedItemsIndexes.length <= 1)
    return false;
  if (!selectedItemsIndexes.includes(dragItem.index))
    return false;
  if (!isContinuousSequence(selectedItemsIndexes))
    return false;
  if (moveToFinal)
    return true;
  return !selectedItemsIndexes.includes(targetIndex);
}
function processMoveSingleItem(configs) {
  const { listItems, dragItem, targetIndex, moveToFinal } = configs;
  const newList = [...listItems];
  newList.splice(dragItem.index, 1);
  if (moveToFinal) {
    newList.push(dragItem.item);
  }
  else {
    const adjustedIndex = (targetIndex > dragItem.index) ? Math.max(0, targetIndex - 1) : targetIndex;
    newList.splice(adjustedIndex, 0, dragItem.item);
  }
  return newList;
}
function processMoveMultipleItems(configs) {
  const { listItems, moveToFinal, targetIndex } = configs;
  const selectedItems = listItems.filter(item => item.selected);
  const selectedItemsIndexes = getSelectedIndices(listItems);
  const minorIndex = Math.min(...selectedItemsIndexes);
  const majorIndex = Math.max(...selectedItemsIndexes);
  const qtdToMove = selectedItems.length;
  const newList = [...listItems];
  newList.splice(minorIndex, qtdToMove);
  if (moveToFinal) {
    newList.push(...selectedItems);
  }
  else {
    let adjustedIndex = (targetIndex > majorIndex) ? Math.max(0, targetIndex - qtdToMove) : targetIndex;
    newList.splice(adjustedIndex, 0, ...selectedItems);
  }
  return newList;
}
export function isContinuousSequence(numbers) {
  if (numbers.length === 0)
    return false;
  const sortedNumbers = [...numbers].sort((a, b) => a - b);
  for (let i = 1; i < sortedNumbers.length; i++) {
    if (sortedNumbers[i] !== sortedNumbers[i - 1] + 1) {
      return false;
    }
  }
  return true;
}
function getSelectedIndices(listItems) {
  return listItems.reduce((indices, item, index) => {
    if (item.selected) {
      indices.push(index);
    }
    return indices;
  }, []);
}
