import { invariant } from "../../../invariant";
import whatIsDraggedOver from "../../droppable/what-is-dragged-over";
import recomputeDisplacementVisibility from "../../update-displacement-visibility/recompute";
import getClientBorderBoxCenter from "../../get-center-from-impact/get-client-border-box-center";
import update from "./update";

const refreshSnap = ({ state, dimensions: forcedDimensions, viewport: forcedViewport }) => {
  invariant(state.movementMode === "SNAP");
  const needsVisibilityCheck = state.impact;
  const viewport = forcedViewport || state.viewport;
  const dimensions = forcedDimensions || state.dimensions;
  const { draggables, droppables } = dimensions;
  const draggable = draggables[state.critical.draggable.id];
  const isOver = whatIsDraggedOver(needsVisibilityCheck);
  invariant(isOver, "Must be over a destination in SNAP movement mode");
  const destination = droppables[isOver];
  const impact = recomputeDisplacementVisibility({
    impact: needsVisibilityCheck,
    viewport,
    destination,
    draggables
  });
  const clientSelection = getClientBorderBoxCenter({
    impact,
    draggable,
    droppable: destination,
    draggables,
    viewport,
    afterCritical: state.afterCritical
  });
  return update({
    // new
    impact,
    clientSelection,
    // pass through
    state,
    dimensions,
    viewport
  });
};

export default refreshSnap;
