import { ActionIcon, Box, Menu, Typography } from '@tidbcloud/uikit'
import { MRT_ColumnDef, ProTable } from '@tidbcloud/uikit/biz'
import { IconDotsHorizontal } from '@tidbcloud/uikit/icons'
import { capitalize } from 'lodash-es'
import { observer } from 'mobx-react'
import { useState } from 'react'
import { useHistory, useParams } from 'react-router-dom'

import { humanByteSize } from 'common/services/prommetric'
import TimeComponent from 'dbaas/components/TimeComponent'
import { useAccessCheck } from 'dbaas/contexts/access-control'
import { deleteBackup, useListBackups } from 'dbaas/services/dataflow'
import { DataflowBackup } from 'dbaas/services/dataflow/interface'
import useStores from 'dbaas/stores/useStores'

import DeleteModal from './DeleteModal'

const RecycleBinCluster = observer(() => {
  const backupActionAccessible = useAccessCheck('ClusterBackupAction')
  const restoreAccessible = useAccessCheck('ClusterRestoreAction')
  const { id: clusterId } = useParams<{ id: string }>()
  const [isDeleteOpen, setIsDeleteOpen] = useState(false)
  const [deletingMap, setDeletingMap] = useState<{ [id: string]: boolean }>({})
  const [deleteId, setDeleteId] = useState<string>('')
  const history = useHistory()
  const {
    store: { tenantData, activeProjectId }
  } = useStores()

  const [currentPage, setCurrentPage] = useState(1)
  const perPage = 20

  const {
    data: backups,
    isLoading,
    refetch
  } = useListBackups(tenantData.id, activeProjectId, clusterId, {
    page: currentPage,
    per_page: perPage
  })

  const totalPage = Math.ceil((backups?.total || 0) / perPage) || 0

  const toggleDeleteModal = (isOpen = false, backupId = '') => {
    setIsDeleteOpen(isOpen)
    setDeleteId(backupId)
  }

  const handleDelete = async () => {
    setDeletingMap((originState) => ({ ...originState, [deleteId]: true }))

    return deleteBackup(tenantData.id, activeProjectId, clusterId, deleteId)
      .then(() => {
        // await sleep(2 * 1000)
        toggleDeleteModal()
        refetch()
      }) // error caught by Form component
      .finally(() => {
        setDeletingMap((originState) => ({
          ...originState,
          [deleteId]: false
        }))
      })
  }

  const columns: MRT_ColumnDef<DataflowBackup>[] = [
    {
      header: 'Backup Time',
      Header: <Box pl={16}>Backup Time</Box>,
      accessorFn: (row) => <Box pl={16}>{<TimeComponent time={row.backup_ts || ''} />}</Box>,
      id: 'backup_ts'
    },
    {
      header: 'Name',
      accessorKey: 'name',
      minSize: 220
    },
    {
      header: 'Type',
      accessorFn: ({ type }) => (type ? capitalize(type) : '-'),
      id: 'type',
      size: 100
    },
    {
      header: 'Size',
      accessorFn: ({ size }: DataflowBackup) => humanByteSize(parseInt(size ?? '0'), false),
      id: 'size',
      size: 100
    },
    {
      header: 'Creation Time',
      accessorFn: (row) => <TimeComponent time={row.created_at || ''} />,
      id: 'created_at'
    },
    {
      header: 'Expiration time',
      accessorFn: (row) => <TimeComponent time={row.expiration_time || ''} />,
      id: 'expiration_time'
    }
  ]

  const actionCol: MRT_ColumnDef<DataflowBackup>[] = [
    {
      header: 'Action',
      size: 50,
      accessorFn: (rowData: DataflowBackup) => {
        const { id } = rowData

        return (
          <Menu>
            <Menu.Target>
              <ActionIcon variant="subtle">
                <IconDotsHorizontal size={16} />
              </ActionIcon>
            </Menu.Target>

            <Menu.Dropdown>
              <Menu.Item
                disabled={!restoreAccessible}
                onClick={() =>
                  history.push(`/project/recycle-bin/${clusterId}/backup/${id}/restore?backupPage=${currentPage}`)
                }
              >
                Restore
              </Menu.Item>
              <Menu.Item
                disabled={!backupActionAccessible || deletingMap[id]}
                onClick={() => toggleDeleteModal(true, id)}
              >
                Delete
              </Menu.Item>
            </Menu.Dropdown>
          </Menu>
        )
      },
      id: 'action'
    }
  ]
  const fullCols = columns.concat(actionCol)

  return (
    <>
      <ProTable
        columns={fullCols}
        data={backups?.items || []}
        loading={isLoading}
        manualPagination={true}
        pagination={{
          total: totalPage,
          value: currentPage || 1,
          onChange: (page) => {
            setCurrentPage(page)
          }
        }}
        errorMessage="No backup data"
      />

      <DeleteModal
        type="backup"
        isOpen={isDeleteOpen}
        isDeleting={deletingMap[deleteId]}
        closeModal={toggleDeleteModal}
        onConfirm={handleDelete}
      >
        <Typography variant="body-lg">The backup can not be recovered, are you sure to delete?</Typography>
      </DeleteModal>
    </>
  )
})

export default RecycleBinCluster
