import { Button, closeAllModals, Group, Modal, notifier, openModal, Stack, Typography } from '@tidbcloud/uikit'
import { ReactNode, useState } from 'react'
import { useHistory } from 'react-router-dom'

import { ChangefeedScaleNg } from 'dbaas/screens/Changefeed/ChangefeedListPremium/ChangefeedScaleNg'
import { SharedTiDB } from 'dbaas/screens/NextGen/shared/model/shared-tidb-state'
import { useNgDeleteChangefeed, useNgPauseChangefeed, useNgResumeChangefeed } from 'dbaas/services/dataflow'
import { ConsoleapiChangefeed } from 'dbaas/services/dataflow/interface'
import { getErrorMessage } from 'dbaas/services/errorCodes'

export const usePremiumChangefeedActions = ({ cluster, refetch }: { cluster: SharedTiDB; refetch?: () => void }) => {
  const history = useHistory()
  const [confirmModal, setConfirmModal] = useState<{
    open: boolean
    title?: ReactNode
    children?: ReactNode
    onConfirm?: () => void
  }>({
    open: false
  })

  const deleteChangefeed = useNgDeleteChangefeed()
  const pauseChangefeed = useNgPauseChangefeed()
  const resumeChangefeed = useNgResumeChangefeed()

  const handlePauseConnector = async (changefeed: ConsoleapiChangefeed) => {
    try {
      await pauseChangefeed.mutateAsync({
        clusterId: cluster.tidbId!,
        changefeedId: changefeed.changefeed_id,
        data: {}
      })
      notifier.success('Changefeed paused successfully')
      setConfirmModal({ open: false })
      refetch?.()
    } catch (error) {
      notifier.error(getErrorMessage(error))
    }
  }

  const handleDeleteConnector = async (changefeed: ConsoleapiChangefeed) => {
    try {
      await deleteChangefeed.mutateAsync({
        clusterId: cluster.tidbId!,
        changefeedId: changefeed.changefeed_id
      })
      notifier.success('Changefeed deleted successfully')
      setConfirmModal({ open: false })
      refetch?.()
    } catch (error) {
      notifier.error(getErrorMessage(error))
    }
  }

  const handleResumeConnector = async (changefeed: ConsoleapiChangefeed) => {
    try {
      notifier.success('Changefeed is resuming...')
      await resumeChangefeed.mutateAsync({
        clusterId: cluster.tidbId!,
        changefeedId: changefeed.changefeed_id,
        data: {}
      })
      setConfirmModal({ open: false })
      notifier.success('Changefeed resumed successfully')
      refetch?.()
    } catch (error) {
      notifier.error(getErrorMessage(error))
    }
  }

  const handleScale = (changefeed: ConsoleapiChangefeed) => {
    openModal({
      title: (
        <Typography c="carbon.9" fw={700} fz={16}>
          Scale Up/Down
        </Typography>
      ),
      centered: true,
      size: 630,
      children: (
        <ChangefeedScaleNg
          changefeed={changefeed}
          cluster={cluster}
          onCancel={closeAllModals}
          onConfirm={() => {
            closeAllModals()
            refetch?.()
          }}
        />
      )
    })
  }

  const handlePause = (changefeed: ConsoleapiChangefeed) => {
    setConfirmModal({
      open: true,
      title: `Confirm to pause ${
        changefeed.name || changefeed.request?.name || `changefeed ${changefeed.changefeed_id}`
      }?`,
      children: (
        <Typography variant="body-lg">
          Please resume the changefeed <b>within 24 hours</b>. If a changefeed is paused for longer, TiDB may garbage
          collect data changes, causing the synchronization to fail. A failed changefeed must be deleted and recreated.
        </Typography>
      ),
      onConfirm: () => {
        handlePauseConnector(changefeed)
      }
    })
  }

  const handleResume = (changefeed: ConsoleapiChangefeed) => {
    handleResumeConnector(changefeed)
  }

  const handleDelete = (changefeed: ConsoleapiChangefeed) => {
    setConfirmModal({
      open: true,
      title: `Confirm to delete ${
        changefeed.name || changefeed.request?.name || `changefeed ${changefeed.changefeed_id}`
      }?`,
      children: (
        <Typography variant="body-lg">
          Once a changefeed is deleted, it cannot be recovered, confirm to delete?
        </Typography>
      ),
      onConfirm: () => {
        handleDeleteConnector(changefeed)
      }
    })
  }

  const handleEdit = (changefeed: ConsoleapiChangefeed) => {
    history.push(`/tidbs/${cluster.tidbId}/changefeed/edit?id=${changefeed.changefeed_id}`)
  }

  const handleView = (changefeed: ConsoleapiChangefeed) => {
    history.push(`/tidbs/${cluster.tidbId}/changefeed/${changefeed.changefeed_id}`)
  }

  const ConfirmModal = (
    <Modal
      opened={confirmModal.open}
      size="lg"
      onClose={() => setConfirmModal({ open: false })}
      title={confirmModal.title}
    >
      <Stack>
        {confirmModal.children}
        <Group justify="flex-end">
          <Button variant="default" onClick={() => setConfirmModal({ open: false })}>
            Cancel
          </Button>
          <Button
            loading={pauseChangefeed.isLoading || resumeChangefeed.isLoading || deleteChangefeed.isLoading}
            onClick={confirmModal?.onConfirm}
            color="red"
            variant="light"
          >
            I understand, continue
          </Button>
        </Group>
      </Stack>
    </Modal>
  )

  return {
    handleScale,
    handlePause,
    handleResume,
    handleDelete,
    handleEdit,
    handleView,
    ConfirmModal
  }
}
