import { ActionIcon, Box, closeAllModals, Group, Menu, notifier, openModal, Text, Typography } from '@tidbcloud/uikit'
import { MRT_ColumnDef, ProTable } from '@tidbcloud/uikit/biz'
import { IconDotsHorizontal } from '@tidbcloud/uikit/icons'
import { useMemoizedFn } from 'ahooks'
import { useState } from 'react'
import { Link, useHistory } from 'react-router-dom'

import { HeroComponent } from 'dbaas/components/Measurement'
import TimeComponent from 'dbaas/components/TimeComponent'
import { AccessCheck } from 'dbaas/contexts/access-control'
import {
  canDeletePremiumDmJob,
  canPausePremiumDmJob,
  canRestartPremiumDmJob,
  canResumePremiumDmJob,
  getModeLabel
} from 'dbaas/features/DataMigration'
import { DmJobStatus } from 'dbaas/features/DataMigration/JobStatus'
import { TableFallback } from 'dbaas/screens/ClusterV2/components/PausedStatus'
import { useSharedTiDBContext } from 'dbaas/screens/NextGen/tidb-mgmt-container/shared/tidb-context'
import { useListPremiumMigrations, usePausePremiumMigration, useResumePremiumMigration } from 'dbaas/services/dataflow'
import { V1beta2PremiumMigration } from 'dbaas/services/dataflow/interface'
import { getErrorMessage } from 'dbaas/services/errorCodes'
import { MixpanelEvents } from 'dbaas/utils/tracking'

import { DeletePremiumDMJob } from './DeletePremiumDMJob'

const usePremiumMigrationJobs = () => {
  const tidb = useSharedTiDBContext()
  const history = useHistory()
  const [pagination, setPagination] = useState<{
    pageIndex: number
    pageSize: number
  }>({
    pageIndex: 0,
    pageSize: 10
  })

  const {
    data: dmJobData,
    isFetched,
    isLoading,
    refetch
  } = useListPremiumMigrations(
    tidb.tidbId!,
    {
      page_token: String(pagination.pageIndex + 1),
      page_size: pagination.pageSize,
      order_by: 'create_time desc'
    },
    {
      query: {
        refetchInterval: 30 * 1000
      }
    }
  )

  const viewJob = useMemoizedFn((id) => {
    history.push(`/tidbs/${tidb.tidbId}/data-migration/${id}`)
  })
  const pauseTask = usePausePremiumMigration()
  const resumeTask = useResumePremiumMigration()

  const columns: MRT_ColumnDef<V1beta2PremiumMigration>[] = [
    {
      header: 'Name',
      Header: () => <Typography pl={16}>Name</Typography>,
      accessorFn: (rowData) => {
        return (
          <Box pl={16}>
            <Link to={`/tidbs/${tidb.tidbId}/data-migration/${rowData.migration_id}`}>{rowData.display_name}</Link>
          </Box>
        )
      }
    },
    {
      header: 'Status',
      size: 100,
      accessorFn: (rowData) => {
        return (
          <Group wrap="nowrap">
            <DmJobStatus status={rowData.state!} />
          </Group>
        )
      }
    },
    {
      header: 'Mode',
      size: 120,
      accessorFn: (rowData) => {
        return getModeLabel(rowData.mode)
      }
    },
    {
      header: 'Target User',
      accessorFn: (rowData) => {
        return rowData.target_user
      }
    },
    {
      header: 'Creation Time',
      accessorFn: (rowData) => {
        return <TimeComponent time={rowData.create_time!} />
      }
    },
    {
      header: '',
      id: 'action',
      size: 80,
      accessorFn: (rowData) => {
        const handleDelete = () => {
          openModal({
            title: (
              <Text c="carbon.9" fw={700} fz={16}>
                Delete Data Migration Job
              </Text>
            ),
            centered: true,
            children: (
              <DeletePremiumDMJob
                job={rowData}
                tidb={tidb}
                onCancel={closeAllModals}
                onConfirm={() => {
                  closeAllModals()
                  refetch()
                }}
              />
            )
          })
        }

        const handlePause = async () => {
          try {
            notifier.success('Migration job pause requested.')
            await pauseTask.mutateAsync({
              tidbId: tidb.tidbId!,
              migrationId: rowData.migration_id!,
              data: {}
            })
            notifier.clear()
            notifier.success('Migration job pause successfully.')
            refetch()
          } catch (e) {
            notifier.error(getErrorMessage(e, true) || 'Failed to pause the job')
          }
        }
        const handleResume = async (from?: 'pause' | 'failed') => {
          try {
            notifier.success(`Migration job ${from === 'pause' ? 'resume' : 'restart'} requested.`)
            await resumeTask.mutateAsync({
              tidbId: tidb.tidbId!,
              migrationId: rowData.migration_id!,
              data: {}
            })
            notifier.clear()
            notifier.success(`Migration job ${from === 'pause' ? 'resume' : 'restart'} successfully.`)

            refetch()
          } catch (e) {
            notifier.error(getErrorMessage(e, true) || 'Failed to resume the job')
          }
        }

        return (
          <Group>
            <Menu shadow="md" width={200}>
              <Menu.Target>
                <ActionIcon variant="subtle" size={32}>
                  <Box c="carbon.8" component={IconDotsHorizontal} size={18} />
                </ActionIcon>
              </Menu.Target>

              <Menu.Dropdown>
                <Menu.Item
                  onClick={() => viewJob(rowData.migration_id)}
                  data-mp-event={MixpanelEvents.PremiumDM.View.ButtonClicked}
                >
                  View
                </Menu.Item>

                <AccessCheck id="TidbxDMAction" scopeProps={{ tidbId: tidb.tidbId }}>
                  {({ accessible }) => (
                    <>
                      {canPausePremiumDmJob(rowData) && (
                        <Menu.Item
                          disabled={!accessible}
                          onClick={handlePause}
                          data-mp-event={MixpanelEvents.PremiumDM.Pause.ButtonClicked}
                        >
                          Pause
                        </Menu.Item>
                      )}

                      {canResumePremiumDmJob(rowData) && (
                        <Menu.Item
                          disabled={!accessible}
                          onClick={() => handleResume('pause')}
                          data-mp-event={MixpanelEvents.PremiumDM.Resume.ButtonClicked}
                        >
                          Resume
                        </Menu.Item>
                      )}

                      {canRestartPremiumDmJob(rowData) && (
                        <Menu.Item
                          disabled={!accessible}
                          onClick={() => handleResume('failed')}
                          data-mp-event={MixpanelEvents.PremiumDM.Restart.ButtonClicked}
                        >
                          Restart
                        </Menu.Item>
                      )}

                      {canDeletePremiumDmJob(rowData) && (
                        <Menu.Item
                          disabled={!accessible}
                          onClick={handleDelete}
                          data-mp-event={MixpanelEvents.PremiumDM.Delete.ButtonClicked}
                        >
                          Delete
                        </Menu.Item>
                      )}
                    </>
                  )}
                </AccessCheck>
              </Menu.Dropdown>
            </Menu>
          </Group>
        )
      }
    }
  ]

  return {
    isFetched,
    columns,
    data: dmJobData?.PremiumMigrations ?? [],
    isLoading,
    pagination,
    setPagination,
    total: dmJobData?.total_size ?? 0
  }
}

export const DataMigrationListPremium = () => {
  const { isFetched, columns, data, isLoading, total, pagination, setPagination } = usePremiumMigrationJobs()
  return (
    <Box>
      {isFetched && <HeroComponent />}

      <ProTable
        columns={columns}
        emptyMessage="No Data Migration Job"
        data={data}
        loading={isLoading}
        manualPagination={true}
        state={{ pagination }}
        onPaginationChange={setPagination}
        rowCount={total || 0}
        pagination={{
          showRowsPerPage: true,
          showTotal: true
        }}
        renderEmptyRowsFallback={() => (
          <TableFallback>
            <TableFallback.Empty
              title="Get started by creating your first data migration"
              desc="Migrate data from MySQL-compatible databases into TiDB Cloud with minimal downtime. This feature supports both full and incremental data migration to ensure your TiDB cluster stays up-to-date with real-time changes."
            />
          </TableFallback>
        )}
        mantineTableProps={{
          highlightOnHover: false
        }}
      />
    </Box>
  )
}
