import getDroppableOver from "../get-droppable-over";
import getDraggablesInsideDroppable from "../get-draggables-inside-droppable";
import withDroppableScroll from "../with-scroll-change/with-droppable-scroll";
import getReorderImpact from "./get-reorder-impact";
import getCombineImpact from "./get-combine-impact";
import noImpact from "../no-impact";
import { offsetRectByPosition } from "../rect";

const getDragImpact = ({ pageOffset, draggable, draggables, droppables, previousImpact, viewport, afterCritical }) => {
  const pageBorderBox = offsetRectByPosition(draggable.page.borderBox, pageOffset);
  const destinationId = getDroppableOver({
    pageBorderBox,
    draggable,
    droppables
  });

  // not dragging over anything

  if (!destinationId) {
    // A big design decision was made here to collapse the home list
    // when not over any list. This yielded the most consistently beautiful experience.
    return noImpact;
  }
  const destination = droppables[destinationId];
  const insideDestination = getDraggablesInsideDroppable(destination.descriptor.id, draggables);

  // Where the element actually is now.
  // Need to take into account the change of scroll in the droppable
  const pageBorderBoxWithDroppableScroll = withDroppableScroll(destination, pageBorderBox);

  // checking combine first so we combine before any reordering
  return (
    getCombineImpact({
      pageBorderBoxWithDroppableScroll,
      draggable,
      previousImpact,
      destination,
      insideDestination,
      afterCritical
    }) ||
    getReorderImpact({
      pageBorderBoxWithDroppableScroll,
      draggable,
      destination,
      insideDestination,
      last: previousImpact.displaced,
      viewport,
      afterCritical
    })
  );
};

export default getDragImpact;
