import { Box, Center, Group, LoadingOverlay, SegmentedControl, Select, Stack } from '@tidbcloud/uikit'
import { IconBlock, IconTableList } from '@tidbcloud/uikit/icons'
import { observer } from 'mobx-react'
import { useState } from 'react'

import { SharedCluster } from 'dbaas/features/ClusterManagement/cluster'
import { useSpecVersionEnabled } from 'dbaas/screens/Cluster/OverviewV2/helpers'
import { useClusterServiceGetCluster } from 'dbaas/services/api-clients/v2023/cluster-management/v1beta1'
import { useClusterServiceListNodeInstances } from 'dbaas/services/api-clients/v2023/dedicated/v1beta1'
import { V1beta1NodeInstanceState } from 'dbaas/services/api-clients/v2023/dedicated/v1beta1/interface'
import useStores from 'dbaas/stores/useStores'
import { eventTracking } from 'dbaas/utils/tracking'

import { TableFallback } from '../../components/PausedStatus'

import { useInstancesDataByType } from './helper'
import { TiDBMap } from './TiDBMap'
import { TiFlashMap } from './TiFlashMap'
import { TiKVMap } from './TiKVMap'

export type NodeInstanceStatus = V1beta1NodeInstanceState | 'ALL'

export type NodeMapLayout = 'table' | 'block'

export const NodeMap = observer(({ cluster }: { cluster: SharedCluster }) => {
  const {
    store: {
      lastVisitLocation: { orgId, projectId }
    }
  } = useStores()

  const [status, setStatus] = useState<NodeInstanceStatus>('ALL')

  const [layout, setLayout] = useState<NodeMapLayout>('table')

  const { data: firstHalfInstances, isLoading: instanceIsLoading } = useClusterServiceListNodeInstances(
    cluster.id,
    { orgId, projectId, pageSize: 100 },
    {
      query: {
        refetchInterval: 1000 * 20,
        refetchOnWindowFocus: false
      }
    }
  )

  const { data: secondHalfInstances } = useClusterServiceListNodeInstances(
    cluster.id,
    { orgId, projectId, pageSize: 100, skip: 100 },
    {
      query: {
        refetchInterval: 1000 * 20,
        refetchOnWindowFocus: false
      }
    }
  )

  const instances = (firstHalfInstances?.nodeInstances ?? []).concat(secondHalfInstances?.nodeInstances ?? [])

  const { data: bffData, isLoading: dedicatedIsLoading } = useClusterServiceGetCluster(
    cluster.id,
    { orgId, projectId },
    {
      query: {
        enabled: !!cluster.id,
        refetchOnWindowFocus: false
      }
    }
  )

  const { tidb, tikv, tiflash } = useInstancesDataByType(instances) ?? false

  const dedicated = bffData?.dedicatedCluster

  const tidbModifying = dedicated?.tidbNodeSetting.tidbNodeGroups.some((v) => v.nodeChangingProgress) ?? false

  const tikvModifying = !!dedicated?.tikvNodeSetting.nodeChangingProgress

  const tiflashModifying = !!dedicated?.tiflashNodeSetting?.nodeChangingProgress

  const { specVersionEnabled } = useSpecVersionEnabled(cluster.provider)

  const tools = (
    <Group>
      <SegmentedControl
        size="md"
        value={layout}
        onChange={(v: NodeMapLayout) => {
          eventTracking(`Nodes ${v} clicked`)
          setLayout(v)
        }}
        data={[
          {
            value: 'table',
            label: (
              <Center>
                <IconTableList size={18} />
              </Center>
            )
          },
          {
            value: 'block',
            label: (
              <Center>
                <IconBlock size={18} />
              </Center>
            )
          }
        ]}
      />
      <Select
        value={status}
        data={[
          { label: 'All', value: 'ALL' },
          { label: 'Available', value: 'AVAILABLE' },
          { label: 'Unavailable', value: 'UNAVAILABLE' },
          { label: 'Creating', value: 'CREATING' },
          { label: 'Deleting', value: 'DELETING' }
        ]}
        onChange={(v) => setStatus(v as NodeInstanceStatus)}
      ></Select>
    </Group>
  )

  let content
  if (cluster?.state === 'PAUSED' && cluster)
    content = (
      <TableFallback.Paused
        cluster={cluster}
        featureName="Nodes"
        featureDesc="Nodes allows you to monitor and modify nodes from TiDB, TiKV and TiFlash (if applicable)."
      />
    )
  else if (cluster?.state === 'PAUSING')
    content = (
      <TableFallback.Empty
        title="Nodes allows you to monitor and modify nodes from TiDB, TiKV and TiFlash (if applicable)."
        desc="The cluster is pausing, and Nodes is inaccessible. "
      />
    )
  else if (cluster?.state === 'RESUMING')
    content = (
      <TableFallback.Empty
        title="Nodes allows you to monitor and modify nodes from TiDB, TiKV and TiFlash (if applicable)."
        desc="The cluster is resuming. Nodes will be accessible after it is active.
  Please wait for a while."
      />
    )
  else
    content = (
      <>
        {tidb.length > 0 && (
          <TiDBMap
            layout={layout}
            status={status}
            modifying={tidbModifying}
            cluster={cluster}
            data={tidb}
            specVersionEnabled={specVersionEnabled}
            nodeSetting={dedicated?.tidbNodeSetting}
          />
        )}
        {tikv.length > 0 && (
          <TiKVMap
            layout={layout}
            status={status}
            modifying={tikvModifying}
            data={tikv}
            specVersionEnabled={specVersionEnabled}
            nodeSetting={dedicated?.tikvNodeSetting}
          />
        )}
        {tiflash.length > 0 && (
          <TiFlashMap
            layout={layout}
            status={status}
            modifying={tiflashModifying}
            data={tiflash}
            nodeSetting={dedicated?.tiflashNodeSetting}
          />
        )}
      </>
    )

  return instanceIsLoading || dedicatedIsLoading ? (
    <Box w="100%" h="100%" style={{ position: 'relative' }}>
      <LoadingOverlay visible={true} />
    </Box>
  ) : (
    <Stack gap={24} mb={70} h="100%">
      {tools}
      {content}
    </Stack>
  )
})
