import {
  ActionIcon,
  Box,
  Button,
  Combobox,
  Divider,
  Flex,
  Group,
  Highlight,
  HoverCard,
  Input,
  Menu,
  ScrollArea,
  Skeleton,
  Stack,
  Typography
} from '@tidbcloud/uikit'
import { IconArrowLeft, IconBuilding05, IconCheck, IconFolder, IconPlus, IconSearchMd } from '@tidbcloud/uikit/icons'
import { observer } from 'mobx-react'
import { useState } from 'react'
import { useHistory } from 'react-router-dom'

import { log } from 'common/log'
import { getSharedCluster } from 'dbaas/features/ClusterManagement/cluster'
import { StateTag } from 'dbaas/screens/Cluster/ClusterInfo'
import { CentralUserProfileOrg, CentralUserProfileProject } from 'dbaas/services/account/interface'
import { useClusterServiceListClusters } from 'dbaas/services/api-clients/v2023/cluster-management/v1beta1'
import useStores from 'dbaas/stores/useStores'
import { eventTracking } from 'dbaas/utils/tracking'

import { useClusterSwitch, useOrgSwitch } from './useNavigationSwitch'
import { useProjectSwitch } from './useNavigationSwitch'

const CREATE_CLUSTER_PATH = '/clusters/create-cluster'
const FAST_SELECT_MAX_WIDTH = 144

export const ClusterPanel = observer(
  ({
    org,
    project,
    onNavigation,
    onBack
  }: {
    org: CentralUserProfileOrg
    project: CentralUserProfileProject
    onNavigation: (clusterId: string) => void
    onBack: () => void
  }) => {
    const history = useHistory()
    const {
      store: {
        lastVisitLocation: { orgId, projectId }
      }
    } = useStores()
    const [search, setSearch] = useState('')
    const orgSwitch = useOrgSwitch()
    const projectSwitch = useProjectSwitch()
    const isOtherOrgSwitch = orgId !== org.id

    return (
      <Box h={354}>
        <Stack gap={4} pr={8}>
          <Group justify="space-between" gap={4} mb={4}>
            <ActionIcon variant="subtle" color="carbon" size="md" onClick={onBack}>
              <IconArrowLeft />
            </ActionIcon>

            <Group gap={2}>
              <Button
                variant="subtle"
                color="carbon"
                size="xs"
                px={8}
                styles={(theme) => ({
                  label: { color: theme.colors.carbon[8] },
                  root: {
                    '&:hover': {
                      backgroundColor: `${theme.colors.carbon[3]} !important`
                    }
                  }
                })}
                onClick={async () => {
                  eventTracking('Organization Changed', {
                    source: 'Global Side Navbar Switcher - Cluster Panel',
                    isOtherOrgSwitch
                  })
                  onNavigation(org.id)
                  orgSwitch(org)
                }}
                maw={FAST_SELECT_MAX_WIDTH}
              >
                <Group sx={{ flexShrink: 0 }} mr={8}>
                  <IconBuilding05 size={16} />
                </Group>
                <Typography sx={{ whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>
                  {org.name}
                </Typography>
              </Button>

              <Typography c="carbon.8">-</Typography>

              <Button
                variant="subtle"
                color="carbon"
                size="xs"
                px={8}
                styles={(theme) => ({
                  label: { color: theme.colors.carbon[8] },
                  root: {
                    '&:hover': {
                      backgroundColor: `${theme.colors.carbon[3]} !important`
                    }
                  }
                })}
                onClick={async () => {
                  eventTracking('Project Changed', {
                    source: 'Global Side Navbar Switcher - Cluster Panel',
                    isOtherOrgSwitch
                  })
                  onNavigation(project.id)
                  projectSwitch(org, project)
                }}
                maw={FAST_SELECT_MAX_WIDTH}
              >
                <Group sx={{ flexShrink: 0 }} mr={8}>
                  <IconFolder size={16} />
                </Group>
                <Typography sx={{ whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>
                  {project.name}
                </Typography>
              </Button>
            </Group>
          </Group>
          <Input
            sx={{ flexGrow: 1 }}
            size="sm"
            placeholder="Find cluster..."
            leftSection={<IconSearchMd size={16} c="gray.9" />}
            value={search}
            onChange={(e) => setSearch(e.currentTarget.value)}
            onClick={() => {
              eventTracking('Click search cluster', {
                source: 'Global Side Navbar Switcher - Cluster Panel'
              })
            }}
          />
          <ScrollArea.Autosize
            type="scroll"
            mr={-8}
            h={355}
            scrollbarSize="var(--combobox-padding)"
            offsetScrollbars="y"
          >
            <ClusterList search={search.trim()} org={org} project={project} onNavigation={onNavigation} />
          </ScrollArea.Autosize>

          <Divider />

          <HoverCard disabled={orgId === org.id}>
            <HoverCard.Target>
              <Box>
                <Button
                  w="100%"
                  variant="transparent"
                  color="peacock"
                  size="sm"
                  disabled={orgId !== org.id}
                  onClick={() => {
                    eventTracking('Click create cluster', {
                      source: 'Global Side Navbar Switcher - Cluster Panel'
                    })
                    onNavigation(project.id)
                    if (projectId !== project.id) {
                      projectSwitch(org, project, CREATE_CLUSTER_PATH)
                      return
                    }

                    history.push(CREATE_CLUSTER_PATH)
                  }}
                >
                  <Group gap={4}>
                    <IconPlus size={16} />
                    <Box>Create Cluster</Box>
                  </Group>
                </Button>
              </Box>
            </HoverCard.Target>
            <HoverCard.Dropdown py={4}>Switch to this organization to create cluster</HoverCard.Dropdown>
          </HoverCard>
        </Stack>
      </Box>
    )
  }
)

const CLUSTER_NUM_PER_PAGE = 99

const ClusterList = observer(
  ({
    search,
    org,
    project,
    onNavigation
  }: {
    search: string
    org: CentralUserProfileOrg
    project: CentralUserProfileProject
    onNavigation: (clusterId: string) => void
  }) => {
    const {
      store: { currentCluster }
    } = useStores()
    const { data, isLoading } = useClusterServiceListClusters(
      {
        orgId: org.id,
        projectId: project.id,
        pageSize: CLUSTER_NUM_PER_PAGE
      },
      {
        query: {
          enabled: !!org.id && !!project.id,
          refetchOnWindowFocus: false,
          onError: (err) => {
            log.error('Failed to fetch cluster list: ', err as Error)
          }
        }
      }
    )
    const clusters = (data?.clusters || [])
      .map((c) => getSharedCluster(c))
      .filter((c) => c?.displayName.toLowerCase().includes(search.toLowerCase()))
      .filter((c) => c !== null)
    const clusterSwitch = useClusterSwitch()

    return (
      <Menu>
        {isLoading && (
          <Stack pl={4} gap={0}>
            {Array(8)
              .fill(undefined)
              .map((_, index) => (
                <Flex key={`skeleton-${index}`} h={34} align="center">
                  <Skeleton height={16} radius="md" />
                </Flex>
              ))}
          </Stack>
        )}
        {!isLoading && !clusters.length && (
          <Typography variant="body-lg" c="carbon.7" px={12}>
            No cluster
          </Typography>
        )}
        {!isLoading &&
          clusters.map((cluster) => {
            const isSelected = currentCluster?.id === cluster?.id
            return (
              <Combobox.Option
                disabled={cluster?.computed.isDedicated && cluster?.computed.creating}
                key={cluster?.id}
                value={cluster?.id || ''}
                onClick={async () => {
                  eventTracking('Cluster Changed', {
                    source: 'Global Side Navbar Switcher - Cluster Panel'
                  })
                  onNavigation(cluster.id)
                  clusterSwitch(org, project, cluster)
                }}
                sx={{
                  wordBreak: 'break-all'
                }}
              >
                <Group gap="xs" justify="space-between" wrap="nowrap">
                  <Group gap="xs" wrap="nowrap">
                    <Box pl={4} mr={-8} my={-8} sx={{ flexShrink: 0 }}>
                      <StateTag displayStatus={cluster.state} badgeOnly />
                    </Box>
                    <Highlight highlight={search}>{cluster.displayName || `Cluster (ID: ${cluster.id})`}</Highlight>
                  </Group>
                  <Group w={16}>{isSelected && <IconCheck c="peacock.7" />}</Group>
                </Group>
              </Combobox.Option>
            )
          })}
      </Menu>
    )
  }
)
