import * as React from 'react';
import { PopoverCommonProps } from '../../common';

export interface DragEndEvent {
  active: {
    id: string;
  };
  over: {
    id: string;
  } | null;
}

export interface DragStartEvent {
  active: {
    id: string;
  };
}

export interface DraggableTableRowProps<E> {
  id: string;
  index: number;
  children?: E;
  isDragOverlay?: boolean;
  isDragAndDropDisabled?: boolean;
}

export interface TableDragAndDrop<
  E extends React.ReactElement<React.HTMLAttributes<HTMLElement>>,
> {
  DroppableTableContext: React.ComponentType<{
    children?: React.ReactNode;
    items: { id: string }[];
    className?: string;
    style?: React.CSSProperties;
    onDragEnd?(event: DragEndEvent): unknown;
    onDragStart?(event: DragStartEvent): unknown;
    onDragCancel?(event: DragEndEvent): unknown;
    isDragAndDropDisabled?: boolean;
    renderRow: (args: {
      rowNum: number;
      rowData: any;
      isDragOverlay: boolean;
    }) => React.ReactElement;
  }>;
  DraggableTableRow: React.ComponentType<DraggableTableRowProps<E>>;
  createDragHandleColumn?: (tableProps: DataTableProps) => DataTableColumn;
}

export type RowDataDefaultType = any;
export interface DataTableProps<RowData = RowDataDefaultType> {
  dataHook?: string;
  id?: string;
  data?: RowData[];
  columns: DataTableColumn<RowData>[];
  showHeaderWhenEmpty?: boolean;
  rowDataHook?: string | DataTableRowDataHookFn<RowData>;
  rowClass?: string;
  headerRowClass?: string;
  headerClass?: string;
  dynamicRowClass?: (rowData: RowData, rowNum: number) => string;
  isRowSelected?: (rowData: RowData, rowNum: number) => boolean;
  isRowHighlight?: (rowData: RowData, rowNum: number) => boolean;
  onRowClick?: (rowData: RowData, rowNum: number) => void;
  onMouseEnterRow?: (rowData: RowData, rowNum: number) => void;
  onMouseLeaveRow?: (rowData: RowData, rowNum: number) => void;
  onSortClick?: (column: DataTableColumn, colNum: number) => void;
  infiniteScroll?: boolean;
  itemsPerPage?: number;
  width?: string;
  skin?: DataTableSkin;
  loadMore?: () => void;
  hasMore?: boolean;
  initialLoad?: boolean;
  loader?: React.ReactNode;
  useWindow?: boolean;
  scrollElement?: HTMLElement | React.RefObject<any>;
  rowVerticalPadding?: DataTableRowVerticalPadding;
  rowDetails?: (rowData: RowData, rowNum: number) => React.ReactNode;
  removeRowDetailsPadding?: boolean;
  allowMultiDetailsExpansion?: boolean;
  hideHeader?: boolean;
  hideHeaderAccessible?: boolean;
  showLastRowDivider?: boolean;
  isApplyColumnWidthStyle?: boolean;
  virtualized?: boolean;
  virtualizedTableHeight?: number;
  virtualizedLineHeight?: number;
  virtualizedListRef?: React.LegacyRef<any>;
  selectedRowsIds?: (string | number)[];
  horizontalScroll?: boolean;
  stickyColumns?: number;
  isRowDisabled?: (rowData: RowData) => boolean;
  infiniteScrollRef?: React.Ref<any>;
  dragAndDrop?: any;
}

export default class DataTable<
  RowData = RowDataDefaultType,
> extends React.Component<DataTableProps<RowData>> {}

export type DataTableColumnAlign = 'start' | 'center' | 'end';
export type DataTableRowDataHookFn<RowData = RowDataDefaultType> = (
  rowData: RowData,
  rowNum: number,
) => string;
export type DataTableSkin = 'standard' | 'neutral';
export type DataTableRowVerticalPadding = 'tiny' | 'small' | 'medium' | 'large';
export interface PopoverPropsWithContent extends PopoverCommonProps {
  content?: React.ReactNode;
}
export type DataTableColumn<RowData = RowDataDefaultType> = {
  dataHook?: string;
  key?: React.Key;
  title: React.ReactNode;
  render: (row: RowData, rowNum: number) => React.ReactNode;
  width?: string | number;
  important?: boolean;
  sortable?: boolean;
  sortDescending?: boolean;
  style?:
    | React.CSSProperties
    | ((
        column: DataTableColumn,
        rowData: RowData,
        rowNum: number,
      ) => React.CSSProperties);
  infoTooltipProps?: PopoverPropsWithContent;
  align?: DataTableColumnAlign;
  stickyActionCell?: boolean;
};
