import {
  Alert,
  Box,
  Button,
  Divider,
  Group,
  List,
  Modal,
  notifier,
  Skeleton,
  Stack,
  Typography
} from '@tidbcloud/uikit'
import DOMPurify from 'dompurify'

import { ModalCodeTitle } from 'dbaas/components'
import { useClusterServiceGetCluster } from 'dbaas/services/api-clients/v2023/cluster-management/v1beta1'
import { useClusterServicePauseCluster } from 'dbaas/services/api-clients/v2023/dedicated/v1beta1'
import { getErrorMessage } from 'dbaas/services/errorCodes'
import useStores from 'dbaas/stores/useStores'
import { MixpanelEvents } from 'dbaas/utils/tracking/event'

import { ClusterNodes, useNewApiFetchClusterCost } from '../cost'

interface DedicatedPauseModalProps {
  clusterId: string
  clusterName: string
  opened: boolean
  onClose: () => void
  onFinish?: () => Promise<unknown>
}

export const DedicatedPauseModal = ({
  clusterId,
  clusterName,
  opened,
  onClose,
  onFinish
}: DedicatedPauseModalProps) => {
  const {
    store: {
      lastVisitLocation: { orgId, projectId }
    }
  } = useStores()
  const clusterQuery = useClusterServiceGetCluster(
    clusterId,
    {
      orgId,
      projectId
    },
    {
      query: {
        enabled: !!(opened && clusterId && orgId && projectId),
        select: (data) => data?.dedicatedCluster,
        refetchOnWindowFocus: false,
        refetchOnMount: false
      }
    }
  )
  const { cloudProvider = '', regionId = '' } = clusterQuery.data || {}
  const region = regionId.replace(/^(aws|gcp|azure)-/, '')

  const nodes: ClusterNodes = {
    tidb: {
      specKey: clusterQuery.data?.tidbNodeSetting?.nodeSpecKey || '',
      nodeGroups: clusterQuery.data?.tidbNodeSetting?.tidbNodeGroups || []
    },
    tikv: {
      specKey: clusterQuery.data?.tikvNodeSetting?.nodeSpecKey || '',
      nodeCount: clusterQuery.data?.tikvNodeSetting?.nodeCount || 0,
      storageGiB: clusterQuery.data?.tikvNodeSetting?.storageSizeGi || 0,
      storageType: clusterQuery.data?.tikvNodeSetting?.storageType
    },
    tiflash: {
      specKey: clusterQuery.data?.tiflashNodeSetting?.nodeSpecKey || '',
      nodeCount: clusterQuery.data?.tiflashNodeSetting?.nodeCount || 0,
      storageGiB: clusterQuery.data?.tiflashNodeSetting?.storageSizeGi || 0,
      storageType: clusterQuery.data?.tiflashNodeSetting?.storageType
    }
  }

  const { query: newApiActiveCostQuery } = useNewApiFetchClusterCost(
    {
      clusterId,
      provider: cloudProvider,
      region,
      paused: false,
      nodes
    },
    {
      query: {
        enabled: opened
      }
    }
  )

  const { query: newApiPausedCostQuery } = useNewApiFetchClusterCost(
    {
      clusterId,
      provider: cloudProvider,
      region,
      paused: true,
      nodes
    },
    {
      query: {
        enabled: opened
      }
    }
  )

  const pauseMutator = useClusterServicePauseCluster({
    mutation: {
      onSuccess: () => {
        clusterQuery.refetch()
        onFinish?.()
        onClose()
        notifier.success('The cluster is pausing.')
      },
      onError: (error) => {
        const message = getErrorMessage(error, true)

        notifier.error(<div dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(message) }} />)
      }
    }
  })
  const onPause = () => {
    return pauseMutator.mutateAsync({ clusterId, params: { orgId, projectId } })
  }

  return (
    <Modal
      size="lg"
      centered
      trapFocus={false}
      opened={opened}
      title={
        <>
          Pause <ModalCodeTitle maxWidth={320}>{clusterName}</ModalCodeTitle> Cluster
        </>
      }
      onClose={onClose}
      styles={{
        body: { padding: 0 }
      }}
    >
      <Stack justify="flex-start" gap="xl" p="xl">
        <Group
          justify="space-between"
          py="md"
          px="xl"
          bg="carbon.2"
          sx={(theme) => ({ borderRadius: theme.radius.md })}
        >
          <Typography variant="label-lg">Cost for available cluster</Typography>
          {clusterQuery.isLoading || newApiActiveCostQuery.isLoading ? (
            <Skeleton width={128} height={30} />
          ) : (
            <Box>
              <Typography variant="headline-md" span>
                ${newApiActiveCostQuery.data?.total || 0}
              </Typography>
              <Typography variant="body-lg" span c="carbon.7">
                /hour
              </Typography>
            </Box>
          )}
        </Group>
        <Group
          justify="space-between"
          py="md"
          px="xl"
          bg="peacock.2"
          sx={(theme) => ({ borderRadius: theme.radius.md })}
        >
          <Typography variant="label-lg">Cost for cluster paused up to 7 Days</Typography>
          {clusterQuery.isLoading || newApiPausedCostQuery.isLoading ? (
            <Skeleton width={128} height={30} />
          ) : (
            <Box>
              <Typography variant="headline-md" span>
                ${newApiPausedCostQuery.data?.total || 0}
              </Typography>
              <Typography variant="body-lg" span c="carbon.7">
                /hour
              </Typography>
            </Box>
          )}
        </Group>
        <Box>
          <Typography variant="label-lg" mb={8}>
            When your cluster is paused
          </Typography>
          <List spacing={8}>
            <List.Item>
              The cluster becomes inaccessible, but your data remains intact, and you can resume operations anytime.
            </List.Item>
            <List.Item>Auto Backup halts, but existing backups remain accessible until their expiration.</List.Item>
            <List.Item>Charges apply only for Node Storage and Data Backup.</List.Item>
          </List>
        </Box>
        <Alert color="yellow">
          If you don't manually resume the cluster within 7 days, TiDB Cloud will automatically do it for you.
        </Alert>
      </Stack>
      <Divider color="carbon.4" />
      <Group justify="flex-end" py="md" px="xl">
        <Button variant="default" onClick={onClose} data-mp-event={MixpanelEvents.DedicatedPause.Run.CancelClicked}>
          Cancel
        </Button>
        <Button
          loading={pauseMutator.isLoading}
          disabled={!clusterId}
          onClick={onPause}
          data-mp-event={MixpanelEvents.DedicatedPause.Run.SubmitClicked}
        >
          Pause
        </Button>
      </Group>
    </Modal>
  )
}
