import { Box, Button, Combobox, Stack, Tooltip, Typography, useCombobox } from '@tidbcloud/uikit'
import { useHover } from '@tidbcloud/uikit/hooks'
import { IconBuilding05, IconFolder, IconServer02 } from '@tidbcloud/uikit/icons'
import { observer } from 'mobx-react'
import { useMemo, useState } from 'react'

import { useGetUserProfileV2 } from 'dbaas/services/account'
import useStores from 'dbaas/stores/useStores'
import { eventTracking } from 'dbaas/utils/tracking'

import { middleEllipsis, MiddleEllipsisText } from '../components/MiddleEllipsisText'

import { ClusterPanel } from './ClusterPanel'
import { OrgProjectPanel } from './OrgProjectPanel'
import { useNavStatus } from './useNavStatus'

const NAME_MAX_WIDTH = 135

export const NavSwitcher = observer(() => {
  const { ref, hovered } = useHover()
  const combobox = useCombobox()
  const {
    store: {
      currentCluster,
      userProfile: { orgs, projects },
      lastVisitLocation: { orgId, projectId }
    }
  } = useStores()
  const { isLoading: isUserProfileLoading } = useGetUserProfileV2({ query: { enabled: false } })
  const { isInOrgPages, isInProjectPages, isInClusterPages } = useNavStatus()
  const org = orgs.find((o) => o.id === orgId)
  const project = projects.find((p) => p.id === projectId)
  const isOrgLoading = isUserProfileLoading
  const isProjectLoading = isUserProfileLoading
  const isClusterLoading = !currentCluster?.displayName && isInClusterPages
  const isLoading = isOrgLoading || isProjectLoading || isClusterLoading
  const inputValue = useMemo(() => {
    if (isLoading) {
      return 'Loading...'
    }
    const orgName = org?.name || org?.id
    const projectName = project?.name || project?.id
    const clusterName = currentCluster?.displayName || currentCluster?.id
    if (isInOrgPages) {
      return orgName || ''
    }
    if (isInProjectPages) {
      return projectName || orgName || ''
    }
    if (isInClusterPages) {
      return clusterName || projectName || orgName || ''
    }
    return ''
  }, [isInOrgPages, isInProjectPages, isInClusterPages, org, project, currentCluster, isLoading])
  const truncatedValue = useMemo(() => middleEllipsis(inputValue, NAME_MAX_WIDTH, '700 14px moderat'), [inputValue])
  const leftIcon = useMemo(() => {
    if (isInOrgPages) {
      return <IconBuilding05 size={16} />
    }
    if (isInProjectPages) {
      return <IconFolder size={16} />
    }
    if (isInClusterPages) {
      return <IconServer02 size={16} />
    }
    return null
  }, [isInOrgPages, isInProjectPages, isInClusterPages])

  return (
    <Box px={16} py={6} mx={-16} my={-6}>
      <Tooltip
        label={inputValue}
        maw={600}
        position="top-start"
        offset={2}
        arrowOffset={100}
        openDelay={400}
        disabled={inputValue === truncatedValue || combobox.dropdownOpened || !hovered}
      >
        <Box>
          <Combobox
            store={combobox}
            __staticSelector="Select"
            width="max-content"
            withinPortal
            onOptionSubmit={() => {}}
            position="bottom-start"
            dropdownPadding={8}
            keepMounted={false}
            withArrow={false}
          >
            <Combobox.Target targetType="button">
              <Button
                ref={ref}
                w="100%"
                variant="default"
                aria-label="Organization/Project/Cluster Navigation"
                data-mp-event="Organization/Project/Cluster nav clicked"
                data-mp-source="Global Side Navbar"
                size="md"
                justify="space-between"
                loading={isLoading}
                leftSection={leftIcon}
                rightSection={<Combobox.Chevron size="md" />}
                onClick={() => {
                  combobox.toggleDropdown()
                }}
                styles={(theme) => ({
                  root: {
                    paddingLeft: `${8}px !important`,
                    paddingRight: `${8}px !important`,
                    backgroundColor: `${theme.colors.carbon[1]} !important`,
                    '&:active': {
                      transform: 'none'
                    }
                  },
                  section: {
                    '& > svg': {
                      color: `${theme.colors.carbon[8]} !important`
                    },
                    '&:where([data-position="left"])': {
                      marginInlineEnd: 8
                    },
                    '&:where([data-position="right"])': {
                      marginInlineStart: 8
                    }
                  },
                  label: {
                    flexGrow: 1,
                    textAlign: 'left'
                  }
                })}
              >
                <Typography
                  sx={{
                    fontWeight: 700,
                    fontSize: 14
                  }}
                >
                  <MiddleEllipsisText text={inputValue} width={NAME_MAX_WIDTH} />
                </Typography>
              </Button>
            </Combobox.Target>
            <Combobox.Dropdown autoFocus>
              <NavSwitcherPanel onNavigation={() => combobox.closeDropdown()} />
            </Combobox.Dropdown>
          </Combobox>
        </Box>
      </Tooltip>
    </Box>
  )
})

enum Layer {
  Org = 'org',
  Cluster = 'cluster'
}

const NavSwitcherPanel = observer(({ onNavigation }: { onNavigation: () => void }) => {
  const {
    store: { tenantData, activeProject }
  } = useStores()
  const { isInOrgPages, isInProjectPages } = useNavStatus()
  const [layer, setLayer] = useState(isInOrgPages || isInProjectPages ? Layer.Org : Layer.Cluster)
  const [org, setOrg] = useState(tenantData)
  const [project, setProject] = useState(activeProject)

  const isInOrgLayer = layer === Layer.Org
  const isInClusterLayer = layer === Layer.Cluster

  return (
    <Box w={350} h={467}>
      <Stack gap={4}>
        <Box sx={{ display: isInOrgLayer ? 'block' : 'none' }}>
          <OrgProjectPanel
            onClickNextLayer={(org, project) => {
              setOrg(org as any)
              setProject(project)
              setLayer(Layer.Cluster)
            }}
            onNavigation={onNavigation}
          />
        </Box>
        <Box sx={{ display: isInClusterLayer ? 'block' : 'none' }}>
          <ClusterPanel
            org={org as any}
            project={project}
            onBack={() => {
              setLayer(Layer.Org)
              eventTracking('Click go to org/project panel', {
                source: 'Global Side Navbar Switcher'
              })
            }}
            onNavigation={onNavigation}
          />
        </Box>
      </Stack>
    </Box>
  )
})
