import * as React from 'react';

type IRenderData = {
  isPlaceholder: boolean;
  depth: number;
  isPreview: boolean;
  connectDragSource: any;
  item: NestableItemProps;
  siblings?: NestableItemProps[];
};

interface NestableItemProps {
  children?: React.ReactNode;
  id?: number | string;
  preventItemChangeDepth?: boolean;
  preventChangeParent?: boolean;
  enforcePinnedOrder?: boolean;
  draggable?: boolean;
  lockDropArea?: boolean;
  isCollapsed?: boolean;
  [key: string]: any;
}

export interface NestableListBaseProps {
  dataHook?: string;
  items?: NestableItemProps[];
  readOnly?: boolean;
  isRenderDraggingChildren?: boolean;
  childrenProperty?: string;
  childrenStyle?: React.CSSProperties;
  onUpdate?: (data: { items: object[]; item: object }) => void;
  useDragHandle?: boolean;
  maxDepth?: number;
  threshold?: number;
  onDragStart?: (itemProps: any) => void;
  onDragEnd?: (itemProps: any) => void;
  renderItem?: (data: IRenderData) => React.ReactNode;
  renderAction?: (data: IRenderData) => React.ReactNode;
  renderPrefix?: (data: IRenderData) => React.ReactNode;
  zIndex?: number;
  /** Defines the zIndex of the draggable layer */
  dragLayerZIndex?: number;
  /** Allows dragging and dropping an item only on its own depth */
  preventChangeDepth?: boolean;
  /** Allows dragging and dropping an item only on its own parent */
  preventChangeParent?: boolean;
  /** Allows dragging and dropping an item only on its pin section */
  enforcePinnedOrder?: boolean;
  /** Returns `false` to reject a drop while the cursor hovers over `hoverItem`.
   * Runs after the built-in constraint flags (`preventChangeDepth`, `preventChangeParent`,
   * `enforcePinnedOrder`). When it returns `false`, no placeholder is shown, the drop
   * is rejected at hover time — matching the behavior of the built-in flags — and a
   * `not-allowed` cursor is shown over the rejected target.
   */
  canDrop?: (
    dragItem: NestableItemProps,
    hoverItem: NestableItemProps,
  ) => boolean;
  /** Allows windowed rendering of large lists. Requires `itemHeight` and `viewportHeight`.
   * @default false
   */
  virtualized?: boolean;
  /** Sets the fixed row height in pixels. Required when `virtualized` is `true`. */
  itemHeight?: number;
  /** Sets the scroll viewport height in pixels. Required when `virtualized` is `true`. */
  viewportHeight?: number;
  /** Sets the number of extra rows to render above and below the visible window.
   * @default 5
   */
  offscreenRowCount?: number;
  /** Sets the id of an item to keep mounted in the window even when scrolled offscreen (e.g., to preserve keyboard focus). */
  pinnedItemId?: number | string;
}

export default class NestableListBase extends React.PureComponent<NestableListBaseProps> {}
