import * as React from 'react';

export interface DraggableProps {
  /** indicates if element can be drop at this place
   * @default true
   */
  droppable?: boolean;
  /** decide whether to render a handle using `connectHandle` (see below) */
  withHandle?: boolean;
  /** uniq id of container that contain current draggable item */
  containerId?: string;
  groupName?: string;
  renderItem?: (data: object) => React.ReactNode;
  index?: number;
  id?: number | string;
  item?: object;
  /** callback when item was moved out from current container to another container */
  onMoveOut?: (id: any) => void;
  /** callback when item was dropped in a new location */
  onDrop?: DropEventFn;
  /** callback when item is hovered*/
  onHover?: HoverEventFn;
  /** callback for drag start */
  onDragStart?: DragEventFn;
  /** callback for drag end */
  onDragEnd?: DragEventFn;
  /** visual positioning shifting for an element (transform: translate) without moving it from its real position at DOM (left, top) */
  shift?: number[];
  /** flag that indicates that there's an item being dragged */
  hasDragged?: boolean;
  /** sets draggable item node & additional info for animation positions calculations */
  setWrapperNode?: (node: HTMLElement, index: number, item: object) => void;
  /** animation duration in ms, default = 0 - disabled */
  animationDuration?: number;
  /** animation timing function, default = linear */
  animationTiming?: string;
  /** callback that could prevent item from dragging */
  canDrag?: DragEventFn;
  delay?: number;
  /**
   In case that you are using some external props inside of renderItems method,
   you need to define them here.
   
   renderItem = ({ item }) => <div key={item.id}>{this.props.myAwesomeProp}</div>
   
   render() {
   return (
   <SortableListBase
   ...
   listOfPropsThatAffectItems={[this.props.myAwesomeProp]}
   />
   )
   }
   */
  listOfPropsThatAffectItems?: any[];
}

export default class Draggable extends React.Component<DraggableProps> {}

export type DragEventParams = {
  id: string | number;
  index: number;
  /** uniq id of container that contain current draggable item */
  containerId: string;
  groupName: string;
  item: object;
};

export type DragEventFn = (params: DragEventParams) => void;

export type HoverEventFn = (params: {
  removedIndex: number | string;
  addedIndex: number | string;
  id: any;
  item: object;
}) => void;

export type DropEventFn = (params: {
  payload: { id: number | string; text: string };
  removedIndex: number;
  addedIndex: number;
  addedToContainerId: string;
  removedFromContainerId: string;
}) => void;
