import { VirtualizedTable } from '@tidb-cloud/ui-components/components/Table/Virtualized'
import { MultilineText } from '@tidb-cloud/ui-components/components/Text'
import { Box } from '@tidbcloud/uikit'
import { useElementSize } from '@tidbcloud/uikit/hooks'
import { rgba } from '@tidbcloud/uikit/utils'
import { observer } from 'mobx-react'
import { useEffect, useMemo, useRef } from 'react'
import { Column } from 'react-table'

import { measureText } from 'dbaas/utils/dom'

import { RunSuccTips } from './RunningTips'

const BASE_HEIGHT = 32
const BASE_LINE_HEIGHT = 24
const BASE_PADDING = 16
const MAX_COL_WIDTH = 300

const Results: React.FC<
  React.PropsWithChildren<{
    tips: React.ReactElement
    showTips: boolean
    list: string[][]
    columns: { col: string }[]
    message: string
    highlightKey?: string
    height: number
    databases?: string[]
    limit?: number
    row_count?: number
  }>
> = ({ tips = null, showTips, list: originList = [], columns = [], message = '', highlightKey = '', height }) => {
  const gridRef = useRef<any>(null)
  const { ref: logRef, width: logWidth } = useElementSize()

  const filterList = useMemo(() => {
    if (!highlightKey) {
      return originList
    }

    return originList.filter((item) => {
      return item.some((col) => col.toLowerCase().includes(highlightKey.toLowerCase()))
    })
  }, [originList, highlightKey])

  useEffect(() => {
    if (gridRef.current) {
      gridRef.current.resetAfterRowIndex(0, false)
    }
  }, [height])

  const w = useMemo(() => {
    let sumW = 0
    const res: number[] = []

    for (let i = 0; i < columns.length; i++) {
      let max = 0

      const col = filterList.map((item) => {
        return measureText(item[i])
      })
      // the text will be hidden, if the width greater than 300
      max = Math.min(Math.ceil(Math.max(...col, measureText(columns[i].col))) + BASE_PADDING * 2, MAX_COL_WIDTH)
      sumW += max
      res.push(max)
    }

    return {
      widths: res,
      total: sumW
    }
  }, [filterList, columns])

  const delta = w.total > logWidth ? 0 : (logWidth - w.total) / columns.length

  const tableColumns: Column<any>[] = useMemo(() => {
    return columns.map((col, colIndex) => {
      return {
        id: col.col + colIndex.toString(),
        Header: (
          <Box
            sx={{
              overflow: 'hidden',
              textOverflow: 'ellipsis',
              paddingRight: 16
            }}
          >
            {col.col}
          </Box>
        ),
        height: BASE_HEIGHT,
        minWidth: 20,
        width: w.widths[colIndex] + delta,
        background: 'red',
        accessor: (_row, rowIndex) => {
          const isHighlight =
            highlightKey && (filterList[rowIndex][colIndex] || '').toLowerCase().includes(highlightKey.toLowerCase())
          return (
            <Box
              sx={(t) => ({
                overflow: 'hidden',
                textOverflow: 'ellipsis',
                height: isHighlight ? `calc(100% + 1rem)` : '',
                margin: isHighlight ? '-.5rem' : 0,
                padding: isHighlight ? '.5rem' : 0,
                backgroundColor: isHighlight ? rgba(t.colors.blue[7], 0.1) : ''
              })}
            >
              <MultilineText text={filterList[rowIndex][colIndex]}></MultilineText>
            </Box>
          )
        }
      }
    })
  }, [columns, w.widths, filterList, delta, highlightKey])

  const h = useMemo(() => {
    const res: number[] = []
    let sumH = 0
    for (let i = 0; i < filterList.length; i++) {
      let height = BASE_HEIGHT
      for (let j = 0; j < filterList[i].length; j++) {
        const cur = filterList[i][j].split('\n').length
        height = Math.max(height, BASE_LINE_HEIGHT * cur)
      }
      sumH += height
      res.push(height)
    }

    return { heights: res, total: sumH }
  }, [filterList])

  return (
    <Box
      sx={(theme) => ({
        overflow: 'auto',
        scrollbarWidth: 'none',
        borderTop: !!originList.length ? `1px solid ${theme.colors.carbon[4]}` : '',
        '&::-webkit-scrollbar': {
          width: 0,
          '&:horizontal': {
            height: 0
          }
        }
      })}
      ref={logRef}
    >
      {!!filterList.length && (
        <VirtualizedTable
          columns={tableColumns}
          data={filterList}
          height={height - 2 - (showTips ? 32 : 0)}
          bodyHeight={h.total}
          itemSize={(index) => {
            return h.heights[index]
          }}
        ></VirtualizedTable>
      )}
      {!!filterList.length && showTips && (
        <Box
          sx={(theme) => ({
            width: '100%',
            height: 34,
            paddingLeft: 16,
            color: theme.colors.carbon[7],
            border: `1px solid ${theme.colors.carbon[4]}`,
            fontSize: 12,
            lineHeight: '32px',
            borderLeft: 'none',
            display: tips ? 'block' : 'none',
            position: 'fixed',
            backgroundColor: theme.white,
            bottom: 0
          })}
        >
          {tips}
        </Box>
      )}
      {!filterList.length && (
        <Box p={24}>
          <RunSuccTips hideTitle={!!originList.length} message={message || 'empty set'} />
        </Box>
      )}
    </Box>
  )
}

export default observer(Results)
