import type { NonIdealStateProps } from '@blueprintjs/core'
import type { CSSProperties, Dispatch, ReactNode, SetStateAction } from 'react'

export enum SortingOrder {
  ASC,
  DESC,
}

export type Column<T> = {
  id: string
  name: string
  display?: boolean
  style?: CSSProperties
  className?: string
  renderValue: (value: T) => ReactNode
  valueStyle?: (value: T) => CSSProperties | undefined
  valueClassName?: (value: T) => string
} & (
  | {
      sortingFunction?: never
      defaultSortingOrder?: never
    }
  | {
      sortingFunction: (a: T, b: T) => number
      defaultSortingOrder?: SortingOrder
    }
)

export type Row<T> = {
  id: string
  value: T
  style?: CSSProperties
  className?: string
  onClick?: () => void
}

export type SelectingRow<T> = Row<T> & {
  onClick: () => void
  isSelected: boolean
}

export type TableProps<T> = {
  columns: Column<T>[]
  className?: string
  style?: CSSProperties
  loading?: boolean
  noDataStateProps?: NonIdealStateProps
  defaultSortByColumnId?: string
} & (
  | {
      rows: Row<T>[]
      allSelected?: never
      onSelectAll?: never
      onDeselectAll?: never
    }
  | {
      rows: SelectingRow<T>[]
      allSelected: boolean
      onSelectAll: () => void
      onDeselectAll: () => void
    }
)

export type SortingOrders = {
  [columnId: string]: SortingOrder
}

export type HeadProps<T> = {
  columns: Column<T>[]
  sortByColumnId: string | undefined
  setSortByColumnId: Dispatch<SetStateAction<string | undefined>>
  sortingOrders: SortingOrders
  setSortingOrders: Dispatch<SetStateAction<SortingOrders>>
} & (
  | {
      allSelected?: never
      onSelectAll?: never
      onDeselectAll?: never
    }
  | {
      allSelected: boolean
      onSelectAll: () => void
      onDeselectAll: () => void
    }
)
