import React, { useEffect, useMemo } from 'react'

import {
  MRT_SortingState,
  ProTable,
  ProTableOptions
} from '@tidbcloud/uikit/biz'

import { useStatementColumns } from './columns'
import { getStatementRecordKey } from './statementV2'
import type { StatementV2Model } from './types'
import { useStatementV2UrlState } from './url-state'

interface ListTableProps {
  data: StatementV2Model[]
  loading?: boolean
  stripUserPrefix: boolean
  ruMetricAvailable: boolean
  seriesColorMap?: Record<string, string>
  highlightedKey?: string
  onRowHover?: (rowKey: string) => void
  onRowLeave?: () => void
  onRowClick?: (row: StatementV2Model) => void
  sortBy?: MRT_SortingState
  onSortChange?: ProTableOptions['onSortingChange']
}

export default function ListTable({
  data,
  loading,
  stripUserPrefix,
  ruMetricAvailable,
  seriesColorMap,
  highlightedKey,
  onRowHover,
  onRowLeave,
  onRowClick,
  sortBy = [],
  onSortChange
}: ListTableProps) {
  const { pagination, setPagination } = useStatementV2UrlState()
  const columns = useStatementColumns(
    stripUserPrefix,
    ruMetricAvailable,
    seriesColorMap
  )

  const sortedData = useMemo(() => {
    if (!sortBy[0]) return data
    const [{ id, desc }] = sortBy
    return [...data].sort((left, right) => {
      const leftValue = left[id as keyof StatementV2Model] ?? 0
      const rightValue = right[id as keyof StatementV2Model] ?? 0
      if (leftValue === rightValue) return 0
      return desc
        ? leftValue > rightValue
          ? -1
          : 1
        : leftValue > rightValue
        ? 1
        : -1
    })
  }, [data, sortBy])

  const totalPages = Math.ceil(sortedData.length / pagination.pageSize)
  const effectivePage = totalPages
    ? Math.min(pagination.curPage, totalPages)
    : 1

  useEffect(() => {
    if (pagination.curPage !== effectivePage) {
      setPagination({ ...pagination, curPage: effectivePage })
    }
  }, [effectivePage, pagination, setPagination])

  const pageData = useMemo(
    () =>
      sortedData.slice(
        (effectivePage - 1) * pagination.pageSize,
        effectivePage * pagination.pageSize
      ),
    [effectivePage, pagination.pageSize, sortedData]
  )

  return (
    <ProTable<StatementV2Model>
      data-testid='statement-v2-table'
      emptyMessage='No Data'
      enableSorting
      manualSorting
      enableColumnPinning
      sortDescFirst
      layoutMode='grid'
      enableColumnResizing
      columns={columns}
      onSortingChange={onSortChange}
      data={pageData}
      state={{ sorting: sortBy, isLoading: loading }}
      initialState={{ columnPinning: { left: ['digest_text'] } }}
      mantinePaperProps={{ mx: 24 }}
      mantineTableBodyRowProps={({ row }) => {
        const rowKey = getStatementRecordKey(row.original)
        const highlightKey = row.original.digest || rowKey

        return row.original.digest_text || row.original.digest
          ? {
              'data-testid': 'statement-v2-table-row',
              onClick: (event) => {
                const selection =
                  event.currentTarget.ownerDocument.getSelection()
                if (loading || (selection && !selection.isCollapsed)) return
                onRowClick?.(row.original)
              },
              onMouseEnter: () => onRowHover?.(highlightKey),
              onMouseLeave: onRowLeave,
              sx: (theme) => ({
                cursor: 'pointer',
                backgroundColor:
                  highlightedKey === highlightKey
                    ? theme.colors.carbon[1]
                    : undefined
              })
            }
          : {}
      }}
      manualPagination
      pagination={{
        value: effectivePage,
        total: totalPages,
        onChange: (curPage) => setPagination({ ...pagination, curPage })
      }}
    />
  )
}
