import { getValueFormat } from '@baurine/grafana-value-formats'
import { Text, Tooltip, Typography } from '@tidbcloud/uikit'

import { SlowquerySlowLogRespItem } from 'dbaas/services/ngm/interface'

import InfoTable from '../../components/InfoTable'

type SlowQueryDetailTimeData = SlowquerySlowLogRespItem & {
  ia_remote_read_segment_wait_time?: number
}

const DetailTime: React.FC<React.PropsWithChildren<{ data: SlowQueryDetailTimeData; isEssential: boolean }>> = ({
  data,
  isEssential
}) => {
  const shouldShowIaRemoteReadSegmentWaitTime = isEssential && data.ia_remote_read_segment_wait_time != null

  return (
    <InfoTable<{
      name: React.ReactNode
      time: number
      level?: number
      description?: string
    }>
      columns={[
        {
          key: 'name',
          name: 'Name',
          element: ({ data, value, rowIndex }) => {
            const d = data[rowIndex]
            return <Text pl={d.level && d.level * 24}>{value}</Text>
          }
        },
        {
          key: 'time',
          name: 'Time',
          tdStyle: { maxWidth: '200px' },
          element: ({ value }) => {
            return <Typography w="80px">{getValueFormat('ns')(value, 1)}</Typography>
          }
        },
        {
          key: 'description',
          name: 'Description',
          tdStyle: { maxWidth: '400px' },
          element: ({ value }) => (
            <Tooltip label={value} position="top-start" withArrow maw={300} multiline>
              <Text className="wd-truncate">{value}</Text>
            </Tooltip>
          )
        }
      ]}
      data={[
        {
          name: <Text fw="bold">Query Time</Text>,
          time: data.query_time! * 10e8,
          description: 'The elapsed wall time when execution the query'
        },
        {
          name: 'Parse Time',
          time: data.parse_time! * 10e8,
          level: 1,
          description: 'Time consumed when parsing the query'
        },
        {
          name: 'Generate Plan Time',
          time: data.compile_time! * 10e8,
          level: 1,
          description: ''
        },
        {
          name: 'Rewrite Plan Time',
          time: data.rewrite_time! * 10e8,
          level: 2,
          description: ''
        },
        {
          name: 'Preprocess Sub-Query Time',
          time: data.preproc_subqueries_time! * 10e8,
          level: 3,
          description: 'Time consumed when pre-processing the subquery during the rewrite plan phase'
        },
        {
          name: 'Optimize Plan Time',
          time: data.optimize_time! * 10e8,
          level: 2
        },
        {
          name: 'Coprocessor Executor Time',
          time: data.cop_time! * 10e8,
          level: 1,
          description:
            'The elapsed wall time when TiDB Coprocessor executor waiting all Coprocessor requests to finish (note: when there are JOIN in SQL statement, multiple TiDB Coprocessor executors may be running in parallel, which may cause this time not being a wall time)'
        },
        {
          name: 'Coprocessor Wait Time',
          time: data.wait_time! * 10e8,
          level: 2,
          description:
            'The total time of Coprocessor request is prepared and wait to execute in TiKV, which may happen when retrieving a snapshot though Raft concensus protocol (note: TiKV waits requests in parallel so that this is not a wall time)'
        },
        {
          name: 'Coprocessor Process Time',
          time: data.process_time! * 10e8,
          level: 2,
          description:
            'The total time of Coprocessor request being executed in TiKV (note: TiKV executes requests in parallel so that this is not a wall time)'
        },
        {
          name: 'Local Latch Wait Time',
          time: data.local_latch_wait_time! * 10e8,
          level: 1,
          description:
            'Time consumed when TiDB waits for the lock in the current TiDB instance before 2PC commit phase when transaction commits'
        },
        {
          name: 'Lock Keys Time',
          time: data.lock_keys_time! * 10e8,
          level: 1,
          description: 'Time consumed when locking keys in pessimistic transaction'
        },
        {
          name: 'Resolve Lock Time',
          time: data.resolve_lock_time! * 10e8,
          level: 1,
          description:
            'Time consumed when TiDB resolves locks from other transactions in 2PC prewrite phase when transaction commits'
        },
        {
          name: 'Get Start Ts Time',
          time: data.wait_ts! * 10e8,
          level: 1,
          description: 'Time consumed when getting a start timestamp when transaction begins'
        },
        {
          name: 'Get Commit Ts Time',
          time: data.get_commit_ts_time! * 10e8,
          level: 1,
          description: 'Time consumed when getting a commit timestamp for 2PC commit phase when transaction commits'
        },
        {
          name: 'Prewrite Time',
          time: data.prewrite_time! * 10e8,
          level: 1,
          description: 'Time consumed in 2PC prewrite phase when transaction commits'
        },
        {
          name: 'Commit Time',
          time: data.commit_time! * 10e8,
          level: 1,
          description: 'Time consumed in 2PC commit phase when transaction commits'
        },
        {
          name: 'Execution Backoff Time',
          time: data.backoff_time! * 10e8,
          level: 1,
          description:
            'The total backoff waiting time before retry when a query encounters errors (note: there may be multiple backoffs in parallel so that this may not be a wall time)'
        },
        {
          name: 'Commit Backoff Time',
          time: data.commit_backoff_time! * 10e8,
          level: 1,
          description:
            'The total backoff waiting time when 2PC commit encounters errors (note: there may be multiple backoffs in parallel so that this may not be a wall time)'
        },
        {
          name: 'Retried execution Time',
          time: data.exec_retry_time! * 10e8,
          level: 1,
          description:
            'Wall time consumed when SQL statement is retried and executed again, except for the last exection'
        },
        {
          name: 'Send response Time',
          time: data.write_sql_response_total! * 10e8,
          level: 1,
          description: 'Time consumed when sending response to the SQL client'
        },
        {
          name: 'Wait Binlog Prewrite Time',
          time: data.wait_prewrite_binlog_time! * 10e8,
          level: 1,
          description: 'Time consumed when waiting Binlog prewrite to finish'
        },
        {
          name: 'The total time queued by RC',
          time: data.time_queued_by_rc! * 10e8,
          level: 1,
          description:
            'The total wait time spent in the resource queue (note: TiKV executes requests in parallel so that this is not a wall time)'
        },
        ...(shouldShowIaRemoteReadSegmentWaitTime
          ? [
              {
                name: 'IA Remote Read Segment Wait Time',
                time: data.ia_remote_read_segment_wait_time! * 10e8,
                level: 1,
                description: 'The wait time spent reading IA remote segments'
              }
            ]
          : [])
      ]}
    />
  )
}

export default DetailTime
