import React, { MouseEvent, ReactNode } from 'react'
import { ScrollBarProps } from 'react-perfect-scrollbar'

declare type ClassNameCalc = string | ((index: number) => string)

/**
 * When the span is equal to 0, the node will not render
 * */
interface SpanInfo {
  colSpan?: number
  rowSpan?: number
}

interface Column<T = any, Options = any> {
  className?: ClassNameCalc
  th:
    | ReactNode
    | ((
        rowIndex: number,
        columnIndex: number,
        options: Options,
        column: Column,
      ) => ReactNode)
  props?: SpanInfo & {
    width?: string | number
  }

  td(
    rowData: T,
    dataIndex: number,
    options: Options,
    column: Column,
    virtualScrollEnable?: boolean,
  ): ReactNode

  [key: string]: any

  [key: number]: any
}

interface ColumnWithChildren<T = any, Options = any> {
  className?: ClassNameCalc
  th:
    | ReactNode
    | ((
        rowIndex: number,
        columnIndex: number,
        options: Options,
        column: Column,
      ) => ReactNode)
  children: (Column<T, Options> | ColumnWithChildren<T, Options>)[]

  [key: string]: any

  [key: number]: any
}

interface SpanCalculator<T = Column> {
  (column: T, rowIndex: number, columnIndex: number): SpanInfo
}

interface TableProps<T = any, Options = any> {
  data: T[]
  columns: (Column<T, Options> | ColumnWithChildren<T, Options>)[]
  showHead?: boolean
  className?: string
  trClassName?: ClassNameCalc
  emptyPlaceholder?: ReactNode
  spanCalculator?: SpanCalculator<Column<T, Options>>
  /**
   * Table options for Column['td'] method
   * */
  optionsForTd?: Options

  rowKey?(rowData: T, index: number): string | number

  virtualScrollEnable?: boolean
  onVirtualScroll?: () => void

  /**
   * rowIndex: The thead index is negative
   * */
  onClick?(
    rowIndex: number,
    columnIndex: number,
    ev: MouseEvent<HTMLTableDataCellElement>,
  ): void
}

declare enum ColumnFixType {
  Left = 'left',
  Right = 'right',
}

declare type ExtendColumn<T = any> = (Column<T> | ColumnWithChildren<T>) & {
  fix?: ColumnFixType
}

interface ExtendTableProps extends TableProps {
  columns: ExtendColumn[]
  spanCalculator?: SpanCalculator<ExtendColumn>
  scrollBarProps?: ScrollBarProps & {
    maxHeight: string
    maxWidth: string
  }
}

declare const TableBase: React.FC<TableProps>

declare const TableExtend: React.FC<ExtendTableProps>

export {
  ClassNameCalc,
  Column,
  ColumnFixType,
  ColumnWithChildren,
  ExtendColumn,
  ExtendTableProps,
  SpanCalculator,
  SpanInfo,
  TableBase,
  TableExtend,
  TableProps,
}
