import {
  Text,
  Button,
  ActionIcon,
  Modal,
  Flex,
  MultiSelect,
  Typography,
  Box,
  Card,
  CopyButton,
  Tooltip
} from '@tidbcloud/uikit'
import { ProTable, MRT_ColumnDef } from '@tidbcloud/uikit/biz'
import { IconCopy03, IconTrash01 } from '@tidbcloud/uikit/icons'
import { useEffect, useMemo, useRef, useState } from 'react'
import { useHistory } from 'react-router-dom'

import { useRequestSupport } from 'dbaas/screens/HelpCenter/RequestSupport/helper'
import { useListAppCluster, useCreateAppCluster, useDeleteAppCluster } from 'dbaas/services/dataservice'
import useStores from 'dbaas/stores/useStores'

import { useDataApiContext } from '../../context'
import CreateCluster from '../../Editor/CreateCluster'
import { useFormatClusterList, showErrorMsg } from '../../helpers'
import { DataSourceType } from '../../types'

const LinkedCluster = () => {
  const { orgId, projectId, editApp, editEndpoint, setClusterDataSource } = useDataApiContext()
  const {
    store: { currentCluster }
  } = useStores()
  const [opened, setOpened] = useState(false)
  const [linkedClusters, setLinkedClusters] = useState<string[]>([])
  const history = useHistory()
  const { list: clusterList } = useFormatClusterList()
  const { open: openSupport } = useRequestSupport()
  const [deleteModalOpened, setDeleteModalOpened] = useState(false)
  const deleteInfo = useRef<{ name: string; id: string } | undefined>()

  const { data, refetch: refetchAppClusters } = useListAppCluster(orgId, projectId, `${editApp?.id}`, {
    query: {
      enabled: !!orgId && !!projectId && !!editApp?.id,
      refetchOnWindowFocus: false
    }
  })

  const linkedClusterList = useMemo(() => {
    return (data?.data || []) as DataSourceType[]
  }, [data])

  useEffect(() => {
    if (!opened) {
      setLinkedClusters([])
    }
  }, [opened])

  useEffect(() => {
    setClusterDataSource(linkedClusterList)
  }, [linkedClusterList])

  useEffect(() => {
    refetchAppClusters()
  }, [editApp?.id, editEndpoint?.dataappp_id])

  const mutation = useCreateAppCluster({
    mutation: {
      onSuccess: () => {
        setOpened(false)
        refetchAppClusters()
      },
      onError: (e) => {
        showErrorMsg(e)
      }
    }
  })

  const deleteMutation = useDeleteAppCluster({
    mutation: {
      onSuccess: () => {
        refetchAppClusters()
      },
      onError: (e) => {
        showErrorMsg(e)
      }
    }
  })

  const addCluster = () => {
    mutation.mutateAsync({
      orgId,
      projectId,
      appId: `${editApp?.id}`,
      data: {
        cluster_ids: linkedClusters
      }
    })
  }

  const deleteCluster = (clusterId: string, clusterName: string) => {
    setDeleteModalOpened(true)
    deleteInfo.current = {
      name: clusterName,
      id: clusterId
    }
  }

  const columns = useMemo<MRT_ColumnDef<DataSourceType>[]>(
    () => [
      {
        header: 'Cluster Name',
        accessorFn: (column) => (
          <Typography
            variant="label-sm"
            c="peacock.7"
            sx={{ wordBreak: 'break-all', whiteSpace: 'break-spaces', cursor: 'pointer' }}
            onClick={() => history.push(`/clusters/${column.cluster_id}/overview`)}
          >
            {column.cluster_name}
          </Typography>
        )
      },
      {
        header: 'Cluster ID',
        maxSize: 200,
        accessorFn: (column) => (
          <Flex align="center" gap={4}>
            <Typography variant="body-sm">{column.cluster_id}</Typography>
            <CopyButton value={column.cluster_id}>
              {({ copied, copy }) => (
                <Tooltip
                  label={copied ? 'Copied' : 'Copy'}
                  withArrow
                  multiline
                  maw={300}
                  sx={{ wordBreak: 'break-all', whiteSpace: 'break-spaces' }}
                >
                  <ActionIcon variant="transparent" c="carbon.8" onClick={copy}>
                    <IconCopy03 size={14} />
                  </ActionIcon>
                </Tooltip>
              )}
            </CopyButton>
          </Flex>
        )
      },
      {
        header: 'Plan',
        size: 160,
        accessorFn: (column) => (
          <Typography variant="body-sm">
            {column.tier_type === 'DEPLOY_TYPE_SHARED' ? 'Starter' : 'Dedicated'}
          </Typography>
        )
      },
      {
        header: 'Cloud',
        size: 100,
        accessorFn: (column) => <Typography variant="body-sm">{(column.cloud || '').toUpperCase()}</Typography>
      },
      {
        header: 'Region',
        size: 140,
        accessorFn: (column) => <Typography variant="body-sm">{column.region}</Typography>
      },
      {
        header: 'Action',
        size: 100,
        accessorFn: (column) => (
          <ActionIcon
            variant="subtle"
            disabled={linkedClusterList.length === 1}
            onClick={() => deleteCluster(column.cluster_id, column.cluster_name)}
          >
            <IconTrash01 size={16} />
          </ActionIcon>
        )
      }
    ],
    [linkedClusterList]
  )

  const closeDeleteModal = () => {
    setDeleteModalOpened(false)
    deleteInfo.current = undefined
  }

  return (
    <Card p={24}>
      <Flex justify="space-between" align="center">
        <Box sx={{ whiteSpace: 'break-spaces' }}>
          <Typography variant="title-md" mb={4}>
            Linked Data Sources
          </Typography>
          <Typography variant="body-md" component="span">
            {
              'Choose TiDB Starter as your data sources. If you want to choose TiDB Dedicated (version >= v6.5.0), please'
            }
          </Typography>
          <Typography
            variant="action-md"
            component="span"
            ml={4}
            fw={400}
            sx={{ cursor: 'pointer' }}
            onClick={() => {
              openSupport({
                orgId,
                cluster: currentCluster || undefined
              })
            }}
          >
            contact us
          </Typography>
          .
        </Box>
        <Button
          size="xs"
          h={28}
          variant="default"
          data-mp-event="Add Cluster button clicked"
          data-mp-source="dataapp"
          onClick={() => setOpened(true)}
        >
          Add Cluster
        </Button>
      </Flex>

      {linkedClusterList.length > 0 && (
        <Box mt={12}>
          <ProTable withBorder columns={columns} data={linkedClusterList} emptyMessage="No data" />
        </Box>
      )}

      <Modal
        title="Link Cluster"
        opened={opened}
        centered
        size={500}
        closeOnClickOutside={false}
        onClose={() => setOpened(false)}
      >
        <Typography variant="body-lg" mb={8}>
          Select clusters that allow data service access
        </Typography>
        <MultiSelect
          data={clusterList.filter(
            (cluster) => !linkedClusterList.find((linkedCluster) => linkedCluster.cluster_id === cluster.value)
          )}
          placeholder="Select one or more clusters"
          nothingFoundMessage={<CreateCluster />}
          onChange={(values) => setLinkedClusters(values)}
          styles={() => ({
            pillsList: {
              flexWrap: 'nowrap',
              overflow: 'hidden'
            },
            pill: {
              maxWidth: '30%'
            }
          })}
        />

        <Flex justify="flex-end" sx={{ marginTop: 24 }}>
          <Button
            variant="default"
            sx={() => ({
              marginRight: 16
            })}
            onClick={() => setOpened(false)}
            data-mp-event="mp-cancel-1691461016725"
          >
            Cancel
          </Button>
          <Button
            disabled={!linkedClusters.length}
            loading={mutation.isLoading}
            onClick={addCluster}
            data-mp-event="mp-add-1691461016727"
          >
            Link Cluster
          </Button>
        </Flex>
      </Modal>

      <Modal
        opened={deleteModalOpened}
        onClose={closeDeleteModal}
        title={
          <Flex direction="row">
            <Typography>Unlink Data Source</Typography>
            <Text
              component="span"
              c="carbon.8"
              sx={(theme) => ({
                marginLeft: 8,
                lineHeight: '18px',
                padding: '2px 6px',
                border: `1px solid ${theme.colors.carbon[3]}`,
                backgroundColor: theme.colors.carbon[2],
                borderRadius: 4
              })}
            >
              {deleteInfo.current?.name}
            </Text>
          </Flex>
        }
        trapFocus={false}
        centered={true}
        size={600}
      >
        <>
          <Typography variant="body-lg">
            Are you certain you wish to disconnect the data source
            <Typography variant="title-md" ml={4} mr={4} component="span">
              {deleteInfo.current?.name}
            </Typography>
            from your Data App
            <Typography variant="title-md" ml={4} component="span">
              {editApp?.app_name}
            </Typography>
            ? Please be aware that this action will render certain endpoints non-functional, and it cannot be reversed.
          </Typography>
          <Flex justify="flex-end" align="center" mt={16}>
            <Button variant="default" mr={16} onClick={closeDeleteModal} data-mp-event="mp-cancel-1691461016722">
              Cancel
            </Button>
            <Button
              variant="light"
              color="red"
              loading={deleteMutation.isLoading}
              onClick={async () => {
                await deleteMutation.mutateAsync({
                  orgId,
                  projectId,
                  appId: `${editApp?.id}`,
                  clusterId: `${deleteInfo.current?.id}`
                })
                closeDeleteModal()
              }}
              data-mp-event="mp-unlink-1691461016724"
            >
              Unlink
            </Button>
          </Flex>
        </>
      </Modal>
    </Card>
  )
}

export default LinkedCluster
