import { Badge, Typography } from '@tidbcloud/uikit'
import { MRT_ColumnDef } from '@tidbcloud/uikit/biz'
import { ProTableOptions } from '@tidbcloud/uikit/biz'
import { useMemo, useState } from 'react'

import { FilledTable } from 'dbaas/components/FilledTable'
import TimeComponent from 'dbaas/components/TimeComponent'
import { DtoDataAppLogEntry } from 'dbaas/services/dataservice/interface'

import LogDetail from './LogDetail'

interface Filters {
  sort: keyof DtoDataAppLogEntry | undefined
  desc: boolean | string
}

type onSortChangeFn = Required<ProTableOptions>['onSortingChange']

const LogListTable = ({ requestLogs, loading }: { requestLogs: DtoDataAppLogEntry[]; loading: boolean }) => {
  const [detailOpened, setDetailOpened] = useState(false)
  const [detailItem, setDetailItem] = useState<DtoDataAppLogEntry | null>(null)

  const [{ sort, desc }, setFilters] = useState<Partial<Filters>>({
    sort: 'request_id',
    desc: true
  })

  const onSortChange: onSortChangeFn = (updater) => {
    setFilters(() => {
      const newSort = typeof updater === 'function' ? updater(sortRules) : updater
      return newSort[0]
        ? { sort: newSort[0].id as keyof DtoDataAppLogEntry, desc: newSort[0].desc }
        : { sort: undefined, desc: undefined }
    })
  }

  const sortRules = useMemo(() => {
    return sort ? [{ id: sort, desc: desc !== undefined && !desc ? false : true }] : []
  }, [sort, desc])

  const logData = useMemo(() => {
    if (!requestLogs?.length) {
      return []
    }

    const logs = [...requestLogs]

    if (!sort) {
      return logs
    }

    const numberFields = ['date_time', 'response_time', 'response_size']
    if (numberFields.includes(sort)) {
      return desc === false
        ? logs.sort((a, b) => parseFloat(a[sort] as string) - parseFloat(b[sort] as string))
        : logs.sort((a, b) => parseFloat(b[sort] as string) - parseFloat(a[sort] as string))
    }

    const arrs = logs.sort((a, b) => ((a[sort] as string).localeCompare(b[sort] as string) >= 0 ? 1 : -1))
    return desc === false ? arrs : arrs.reverse()
  }, [sort, desc, requestLogs])

  const ColumnItem = (content: string | React.ReactNode) => {
    return <Typography variant="body-lg">{content}</Typography>
  }

  const columns = useMemo<MRT_ColumnDef<DtoDataAppLogEntry>[]>(
    () => [
      {
        header: 'Request Id',
        id: 'request_id',
        accessorFn: (column) => (
          <Typography
            variant="action-md"
            maw={160}
            fw={400}
            sx={{ cursor: 'pointer', overflow: 'hidden', textOverflow: 'ellipsis' }}
            onClick={() => {
              setDetailOpened(true)
              setDetailItem(column)
            }}
          >
            {column.request_id}
          </Typography>
        )
      },
      {
        header: 'Date Time',
        id: 'date_time',
        size: 170,
        accessorFn: (column) => ColumnItem(<TimeComponent time={column.date_time!} />)
      },
      {
        header: 'Status',
        id: 'status',
        maxSize: 80,
        accessorFn: (column) => (
          <Badge variant="dot" color={column.status === 'Success' ? 'green' : 'red'} sx={{ paddingLeft: 0 }}>
            {ColumnItem(column.status ?? '')}
          </Badge>
        )
      },
      {
        header: 'Type',
        id: 'type',
        maxSize: 80,
        accessorFn: (column) => ColumnItem(column.type ?? '')
      },
      {
        header: 'Name',
        id: 'endpoint_name',
        maxSize: 100,
        accessorFn: (column) => ColumnItem(column.endpoint_name ?? '')
      },
      {
        header: 'Response Time',
        id: 'response_time',
        maxSize: 100,
        accessorFn: (column) => ColumnItem(column.response_time ?? '')
      },
      {
        header: 'Response Size',
        id: 'response_size',
        maxSize: 120,
        accessorFn: (column) => ColumnItem(column.response_size ?? '')
      },
      {
        header: 'Operation Id',
        id: 'endpoint_id',
        maxSize: 140,
        accessorFn: (column) => (
          <Typography
            maw={140}
            variant="body-lg"
            sx={{
              whiteSpace: 'nowrap',
              overflow: 'hidden',
              textOverflow: 'ellipsis'
            }}
          >
            {column.endpoint_id}
          </Typography>
        )
      }
    ],
    [logData]
  )

  return (
    <>
      <FilledTable<DtoDataAppLogEntry>
        highlightOnHover
        enableSorting
        manualSorting
        sortDescFirst
        columns={columns}
        onSortingChange={onSortChange}
        loading={loading}
        data={loading ? [] : logData || []}
        state={{ sorting: sortRules }}
        mantinePaperProps={{ mx: 16 }}
      />

      <LogDetail
        opened={detailOpened}
        close={() => {
          setDetailOpened(false)
          setDetailItem(null)
        }}
        data={detailItem}
      />
    </>
  )
}
export default LogListTable
