import { useDraggableCollection, useDraggableItem, DragPreview, useDroppableItem, useDroppableCollection, useDropIndicator, isVirtualDragging } from '@react-aria/dnd';
export { DIRECTORY_DRAG_TYPE } from '@react-aria/dnd';
import { useDraggableCollectionState, useDroppableCollectionState } from '@react-stately/dnd';
import { useMemo } from 'react';

/**
 * Provides the hooks required to enable drag and drop behavior for a drag and
 * drop compatible component.
 */
// NOTE: if more components become drag-n-droppable move elsewhere.
function useDragAndDrop(options) {
  let dragAndDropHooks = useMemo(() => {
    let {
      onDrop,
      onInsert,
      onItemDrop,
      onReorder,
      onRootDrop,
      getItems
    } = options;
    let isDraggable = !!getItems;
    let isDroppable = !!(onDrop || onInsert || onItemDrop || onReorder || onRootDrop);
    let hooks = {};
    if (isDraggable) {
      // @ts-expect-error
      hooks.useDraggableCollectionState = function useDraggableCollectionStateOverride(props) {
        return useDraggableCollectionState({
          ...props,
          ...options
        });
      };
      hooks.useDraggableCollection = useDraggableCollection;
      hooks.useDraggableItem = useDraggableItem;
      hooks.DragPreview = DragPreview;
    }
    if (isDroppable) {
      // eslint-disable-next-line no-unused-expressions
      hooks.useDroppableCollectionState = function useDroppableCollectionStateOverride(props) {
        return useDroppableCollectionState({
          ...props,
          ...options
        });
      }, hooks.useDroppableItem = useDroppableItem;
      hooks.useDroppableCollection = function useDroppableCollectionOverride(props, state, ref) {
        return useDroppableCollection({
          ...props,
          ...options
        }, state, ref);
      };
      hooks.useDropIndicator = useDropIndicator;
    }
    if (isDraggable || isDroppable) {
      hooks.isVirtualDragging = isVirtualDragging;
    }
    return hooks;
  }, [options]);
  return {
    dragAndDropHooks
  };
}

export { useDragAndDrop };
