import React, { useMemo, useState } from 'react'

import { getValueFormat } from '@baurine/grafana-value-formats'
import {
  Alert,
  Button,
  Card,
  Group,
  LoadingOverlay,
  Modal,
  Progress,
  Stack,
  Text,
  Textarea,
  TextInput,
  Title
} from '@mantine/core'
import { showNotification } from '@mantine/notifications'
import { IconAlertCircle } from '@tabler/icons-react'
import { useNavigate } from 'react-router-dom'

import { delCluster, updateClusterInfo } from '~/api'
import { useCurCluster, useCurOrg } from '~/hooks/state'
import { useMutation } from '~/hooks/use-mutation'

const DeleteClusterConfirm: React.FC<{
  onCancel?: () => void
  onOK?: () => void
  processing?: boolean
}> = ({ onCancel, onOK, processing }) => {
  return (
    <Stack sx={{ position: 'relative' }}>
      <Title order={4}>Delete Cluster</Title>
      <Text color='dimmed'>
        This cluster will be deleted, along with all of its data.
      </Text>
      <Alert icon={<IconAlertCircle size={16} />} color='red'>
        This action is not reversible, please be certain.
      </Alert>
      <Group position='right'>
        <Button variant='default' onClick={onCancel}>
          Cancel
        </Button>
        <Button color='red' onClick={onOK}>
          Delete
        </Button>
      </Group>
      <LoadingOverlay visible={processing ?? false} />
    </Stack>
  )
}

const Page: React.FC = () => {
  const { curOrg } = useCurOrg()
  const { id: oid } = curOrg!

  const { curCluster, reloadCurCluster } = useCurCluster()
  const { id: cid, dataSizeUsed, dataSizeLimit, name, note } = curCluster!

  // data size
  const usedSizePercent = useMemo(() => {
    if (dataSizeUsed && dataSizeLimit) {
      return (dataSizeUsed * 100) / dataSizeLimit
    }
    return 0
  }, [dataSizeUsed, dataSizeLimit])
  const usedSizeText = useMemo(() => {
    return `Used ${getValueFormat('decbytes')(
      dataSizeUsed!,
      2,
      null
    )} / ${getValueFormat('decbytes')(dataSizeLimit!, 2, null)}`
  }, [dataSizeUsed, dataSizeLimit])

  // update cluster
  const [clusterName, setClusterName] = useState(name)
  const [clusterNote, setClusterNote] = useState(note)

  const updateClusterInfoMut = useMutation(updateClusterInfo)

  function handleUpdateCluster() {
    updateClusterInfoMut.run(
      {
        oid: curOrg!.id!,
        cid: cid!,
        req: {
          name: clusterName?.trim(),
          description: clusterNote?.trim()
        }
      },
      () => {
        reloadCurCluster()
      }
    )
  }

  // delete cluster
  const [modalOpen, setModalOpen] = useState(false)
  const delClusterMut = useMutation(delCluster)
  const navigate = useNavigate()

  async function handleDelCluster() {
    await delClusterMut.run({ oid: oid!, cid: cid! }, function () {
      showNotification({
        color: 'teal',
        message: `Cluster ${name} has been deleted successfully`
      })
      navigate(`/orgs/${oid}/clusters`)
    })
    setModalOpen(false)
  }

  return (
    <Stack>
      <Card withBorder>
        <Group position='apart' spacing='xs'>
          <Text fw={500}>Data Size</Text>
          <Text color='dimmed' size='xs'>
            {usedSizeText}
          </Text>
        </Group>
        <Progress value={usedSizePercent} size='lg' my={2} />
        <Text color='dimmed' size='xs'>
          Clinic will automatically delete historical data when capacity limit
          is exceeded
        </Text>
      </Card>

      <Card withBorder>
        <Stack maw={480}>
          <TextInput
            label='Cluster Name'
            value={clusterName}
            onChange={(e) => setClusterName(e.target.value)}
            withAsterisk
            error={
              clusterName?.trim() === '' && 'Cluster name must not be empty'
            }
          />
          <Textarea
            label='Note'
            description='Extra information for the cluster'
            value={clusterNote}
            onChange={(e) => setClusterNote(e.target.value)}
          />
        </Stack>

        <Card.Section withBorder inheritPadding mt='md' py='sm'>
          <Group position='right'>
            <Button
              onClick={handleUpdateCluster}
              loading={updateClusterInfoMut.loading}
              disabled={clusterName?.trim() === ''}
            >
              Save
            </Button>
          </Group>
        </Card.Section>
      </Card>

      <Card withBorder sx={(theme) => ({ borderColor: theme.colors.red[5] })}>
        <Title order={3}>Delete Cluster</Title>
        <Text>
          Permanently remove this cluster and all of its data from PingCAP
          Clinic platform. This action is not reversible, so please continue
          with caution.
        </Text>

        <Card.Section withBorder inheritPadding mt='md' py='sm'>
          <Group position='right'>
            <Button
              color='red'
              loading={delClusterMut.loading}
              onClick={() => setModalOpen(true)}
            >
              Delete
            </Button>
          </Group>
        </Card.Section>
      </Card>

      <Modal
        opened={modalOpen}
        withCloseButton={false}
        onClose={() => setModalOpen(false)}
      >
        <DeleteClusterConfirm
          onCancel={() => setModalOpen(false)}
          onOK={handleDelCluster}
          processing={delClusterMut.loading}
        />
      </Modal>
    </Stack>
  )
}

export default Page
