import { OverflowTooltip } from '@tidb-cloud/ui-components/components/Text'
import { Box, Flex, Typography } from '@tidbcloud/uikit'
import { createStyles } from '@tidbcloud/uikit/emotion'
import { IconMenuLeft } from '@tidbcloud/uikit/icons'
import clsx from 'clsx'
import { throttle } from 'lodash-es'
import { ResizeCallback, ResizeStartCallback } from 're-resizable'
import React, { useState, useMemo } from 'react'

import ResizableContainer from 'dbaas/components/ResizableContainer'
import { eventTracking } from 'dbaas/utils/tracking'

import { DEFAULT_QUERY_LOG_LAYOUT, useSQLEditorContext } from '../context/editor-context'
import { useCommonStyles } from '../index.styles'
import { SqlRes, RequestStatus } from '../types'

import { LayoutIcon } from './Layout'

const useStyles = createStyles((_theme) => {
  return {
    text: {
      display: 'inline-block',
      whiteSpace: 'nowrap',
      overflow: 'hidden',
      textOverflow: 'ellipsis',
      fontSize: 14
    }
  }
})

const getStatusDesc = (status: RequestStatus, time: string) => {
  if (status === RequestStatus.Waiting) {
    return '-'
  }

  if (status === RequestStatus.Loading) {
    return 'Running...'
  }

  if (status === RequestStatus.Error) {
    return 'Query Failed.'
  }

  if (status === RequestStatus.Warning) {
    return 'Query Warning.'
  }

  return `Duration ${time || 0} ms`
}

const Status = ({ status = RequestStatus.Loading }: { status: RequestStatus }) => {
  const map = new Map([
    [RequestStatus.Waiting, 'carbon.6'],
    [RequestStatus.Loading, 'peacock.7'],
    [RequestStatus.Success, 'green.7'],
    [RequestStatus.Error, 'red.7'],
    [RequestStatus.Warning, 'yellow.7']
  ])

  const color = map.get(status) ?? 'carbon.6'
  const colorArr = color.split('.')

  return (
    <Box
      sx={(t) => ({
        display: 'inline-block',
        width: 10,
        height: 10,
        borderRadius: '50%',
        marginTop: 4,
        color: map.get(status) ?? 'carbon.6',
        backgroundColor: t.colors[colorArr[0]][+colorArr[1]]
      })}
    ></Box>
  )
}
export interface QueryLogProps {
  curSelectedLog: number
  onLogClick: (index: number) => void
  maxWidth: number
}

export const QueryLog: React.FC<React.PropsWithChildren<QueryLogProps>> = ({
  curSelectedLog,
  onLogClick,
  maxWidth
}) => {
  const [resizing, setResizing] = useState(false)
  const { sqlResultList } = useSQLEditorContext()
  const { queryLogLayout, setQueryLogLayout } = useSQLEditorContext()
  const [startWidth, setStartWidth] = useState(0)
  const { classes: commonClasses } = useCommonStyles()
  const { classes } = useStyles()

  const onResizeStart: ResizeStartCallback = () => {
    setStartWidth(queryLogLayout.width || DEFAULT_QUERY_LOG_LAYOUT.width)
  }

  const onResize: ResizeCallback = throttle((_event, _direction, _elementRef, delta) => {
    setResizing(true)
    const width = startWidth + delta.width
    setQueryLogLayout({
      width
    })
  }, 10)

  const onResizeStop: ResizeCallback = (_event, _direction, _elementRef, delta) => {
    setResizing(false)
    const width = startWidth + delta.width
    setQueryLogLayout({
      width
    })
  }

  const maxQuerlogWidth = useMemo(() => {
    return maxWidth - 200
  }, [maxWidth])

  return (
    <ResizableContainer
      style={{
        height: '100%',
        border: 'none'
      }}
      className={clsx({
        [commonClasses.resizing]: resizing
      })}
      enable={{ right: queryLogLayout.hidden ? false : true }}
      handleClasses={{ right: commonClasses.resizer }}
      size={{
        width: queryLogLayout.hidden ? 0 : queryLogLayout.width || DEFAULT_QUERY_LOG_LAYOUT.width,
        height: '100%'
      }}
      minWidth={queryLogLayout.hidden ? 0 : DEFAULT_QUERY_LOG_LAYOUT.width}
      maxWidth={maxQuerlogWidth}
      onResizeStart={onResizeStart}
      onResize={onResize}
      onResizeStop={onResizeStop}
    >
      <Flex
        direction="column"
        sx={(theme) => ({
          borderRight: `1px solid ${theme.colors.carbon[3]}`,
          position: 'relative',
          height: '100%',
          overflow: 'hidden',
          transition: 'width 500ms'
        })}
      >
        <Flex justify="space-between" align="center" sx={{ whiteSpace: 'nowrap' }}>
          <Typography variant="label-lg" lh="40px" pl={16}>
            Query log
          </Typography>
          <Box pr={16}>
            {!queryLogLayout.hidden && (
              <LayoutIcon
                onClick={() => {
                  setQueryLogLayout({
                    hidden: true
                  })
                  eventTracking('SQL Editor Query Log Close Button Clicked')
                }}
              >
                <IconMenuLeft size={16} />
              </LayoutIcon>
            )}
          </Box>
        </Flex>
        <Box
          sx={{
            overflowX: 'hidden',
            overflowY: 'auto',
            '&::-webkit-scrollbar': {
              width: 0,

              '&:horizontal': {
                height: 0
              }
            }
          }}
        >
          {sqlResultList?.map((item: SqlRes, index: number) => {
            const sqlText = <Typography sx={{ wordBreak: 'break-all' }}>{item.statement.content}</Typography>
            return (
              <Box
                className="log-item"
                key={index}
                sx={(theme) => ({
                  cursor: 'pointer',
                  padding: '0 16px',
                  backgroundColor: curSelectedLog === index ? theme.colors.peacock[2] : '',
                  '&:hover': {
                    background: curSelectedLog === index ? theme.colors.peacock[2] : theme.colors.carbon[1]
                  }
                })}
                onClick={() => {
                  eventTracking('SQL Editor Query Log Item Clicked', {
                    index
                  })
                  onLogClick(index)
                }}
              >
                {(queryLogLayout.width || DEFAULT_QUERY_LOG_LAYOUT.width) > 400 ? (
                  <Flex lh="40px" align="center" sx={{ overflow: 'hidden' }}>
                    <Typography variant="label-lg" c="carbon.6" miw={40} ta="center">
                      {sqlResultList.length - index}
                    </Typography>
                    <Box>
                      <Status status={item.res?.warn_count ? RequestStatus.Warning : item.status} />
                    </Box>
                    <Flex
                      justify="space-between"
                      align="center"
                      ml={16}
                      sx={(_theme) => ({
                        flex: 1,
                        width: '100%',
                        overflow: 'hidden'
                      })}
                    >
                      <OverflowTooltip
                        label={sqlText}
                        minWidth={280}
                        withArrow
                        position="left"
                        offset={100}
                        className={`${classes.text}`}
                      >
                        {item.statement.content}
                      </OverflowTooltip>
                      <Typography
                        truncate={true}
                        sx={(theme) => ({
                          color: theme.colors.carbon[6],
                          fontSize: 14,
                          flexShrink: 0,
                          marginLeft: 24
                        })}
                      >
                        {getStatusDesc(item.status, item.res?.execute_time || '')}, Rows {item.res?.row_count || 0}
                      </Typography>
                    </Flex>
                  </Flex>
                ) : (
                  <Flex p="4px 0 8px" gap={16}>
                    <Flex direction="column" align="center" color="carbon.6" w={24}>
                      <Box lh="32px">{sqlResultList.length - index}</Box>
                      <Status status={item.res?.warn_count ? RequestStatus.Warning : item.status} />
                    </Flex>
                    <Flex
                      direction="column"
                      sx={{
                        lineHeight: '32px',
                        flex: 1,
                        overflow: 'hidden'
                      }}
                    >
                      <OverflowTooltip
                        label={sqlText}
                        position="left"
                        width={280}
                        offset={46}
                        className={`${classes.text}`}
                      >
                        {item.statement.content}
                      </OverflowTooltip>
                      <Typography
                        truncate={true}
                        sx={(theme) => ({
                          lineHeight: '16px',
                          flex: 1,
                          color: theme.colors.carbon[6],
                          fontSize: 14
                        })}
                      >
                        {getStatusDesc(item.status, item.res?.execute_time || '')}
                      </Typography>
                    </Flex>
                  </Flex>
                )}
              </Box>
            )
          })}
        </Box>
      </Flex>
    </ResizableContainer>
  )
}
