import { Stack, Flex, Box, Card, Typography, Button, Group, Skeleton } from '@tidbcloud/uikit'
import { useDisclosure } from '@tidbcloud/uikit/hooks'
import React, { useEffect } from 'react'
import { useLocation } from 'react-router-dom'

import TimeComponent from 'dbaas/components/TimeComponent'
import { SharedCluster } from 'dbaas/features/ClusterManagement/cluster'
import { DedicatedResumingModal, useFetchPause2024Enabled } from 'dbaas/features/ClusterManagement/dedicated'
import {
  ResourceInsufficientAlert,
  useResourceInsufficientClusterById
} from 'dbaas/features/ClusterManagement/dedicated/ResourceInsufficient'
import { ServicePlanTag } from 'dbaas/screens/NextGen/shared/tidb-instance/service-plan/ServicePlanTag'
import useStores from 'dbaas/stores/useStores'

import PauseOrResumeCluster from '../PauseOrResumeCluster'

import { ClusterPropPanel, ServerlessClusterPropPanel } from './ClusterProperty'
import { ClusterSizePanel } from './ClusterSize'
import { CodeExamplesPanel, CodeExamplesBasePanel } from './CodeExamples'
import { useBFFDedicated, useClusterState } from './helpers'
import MonitorCard from './Monitoring'
import { SpendLimitUsage } from './SpendLimitUsage'
import { StandardCapacity } from './StandardCapacity'

interface SubOverviewProps {
  cluster: SharedCluster
  top?: React.ReactNode
}

const DedicatedOverview = ({ cluster }: SubOverviewProps) => {
  const { isCreating, isRecovering } = useClusterState(cluster)
  const loading = isCreating || isRecovering
  const [resumingModalOpened, resumingModalHandlers] = useDisclosure(false)
  const { dedicated, useBffData, isLoading } = useBFFDedicated(cluster)

  const {
    actions: { fetchCluster }
  } = useStores()

  const clusterState = useClusterState(cluster)

  const isInvalid = clusterState.isPaused || clusterState.isPausing || clusterState.isResuming

  const pause2024ExpQuery = useFetchPause2024Enabled()

  const showResumeTime = useBffData && dedicated && clusterState.isPaused && pause2024ExpQuery.data

  const insufficientCluster = useResourceInsufficientClusterById(cluster.id)

  return (
    <Stack px="xl" gap="xl">
      {insufficientCluster && (
        <ResourceInsufficientAlert
          state={insufficientCluster.dedicatedCluster?.state}
          name={insufficientCluster.dedicatedCluster?.displayName}
        />
      )}
      {isInvalid && (
        <Card p={36}>
          {isLoading ? (
            <Stack px="xl" gap="md">
              <Skeleton h={20} />
              <Skeleton h={20} />
              <Skeleton h={20} />
            </Stack>
          ) : (
            <Group justify="center">
              <Stack align="center" gap="0">
                {clusterState.isPaused && (
                  <>
                    <Typography variant="headline-sm" c={'carbon.7'}>
                      The cluster is paused.
                    </Typography>
                    {showResumeTime ? (
                      <Typography variant="body-md" mt={8} mb={16}>
                        The next auto resume schedule is{' '}
                        <TimeComponent time={dedicated?.pausePlan?.scheduledResumeTime ?? ''} />.
                      </Typography>
                    ) : (
                      <Typography variant="body-md" mt={8} mb={16}>
                        and all features are inaccessible.{' '}
                        <a
                          href="https://docs.pingcap.com/tidbcloud/pause-or-resume-tidb-cluster"
                          target="_blank"
                          rel="noreferrer"
                        >
                          Learn more
                        </a>
                      </Typography>
                    )}
                    <Button onClick={resumingModalHandlers.open} size="xs">
                      Resume
                    </Button>
                  </>
                )}
                {clusterState.isPausing && (
                  <>
                    <Typography variant="body-md">The cluster is pausing,</Typography>
                    <Typography variant="body-md">and all features are inaccessible. </Typography>
                  </>
                )}
                {clusterState.isResuming && (
                  <>
                    <Typography>The cluster is resuming,</Typography>
                    <Typography>and all features will be accessible after it is active.</Typography>
                    <Typography>Please wait for a while.</Typography>
                  </>
                )}
              </Stack>
              {pause2024ExpQuery.data ? (
                <DedicatedResumingModal
                  clusterId={cluster.id}
                  clusterName={cluster.displayName}
                  opened={resumingModalOpened}
                  onClose={resumingModalHandlers.close}
                  onFinish={async () => {
                    await fetchCluster(cluster.id)
                  }}
                />
              ) : (
                <PauseOrResumeCluster
                  id={cluster.id}
                  cluster={cluster}
                  visible={resumingModalOpened}
                  onClose={resumingModalHandlers.close}
                  onFinish={async () => {
                    await fetchCluster(cluster.id)
                  }}
                />
              )}
            </Group>
          )}
        </Card>
      )}
      <Flex
        gap="xl"
        align="stretch"
        miw={505}
        sx={(theme) => ({
          [`@media (max-width: ${theme.breakpoints.lg}px)`]: {
            flexWrap: 'wrap'
          }
        })}
      >
        <Box
          miw={416}
          sx={(theme) => ({
            [`@media (max-width: ${theme.breakpoints.lg}px)`]: {
              flex: 1
            },
            [`@media (min-width: ${theme.breakpoints.lg}px)`]: {
              maxWidth: 480
            }
          })}
        >
          <ClusterPropPanel cluster={cluster} mb="xl" />
          <ClusterSizePanel cluster={cluster} loading={loading} />
        </Box>
        <MonitorCard cluster={cluster} miw={302} sx={{ flex: 1 }} />
      </Flex>
    </Stack>
  )
}

const ServerlessOverview = ({ cluster, top }: SubOverviewProps) => {
  const { state } = useLocation<{ from?: string }>()
  const {
    actions: { fetchCluster }
  } = useStores()

  useEffect(() => {
    // fix capacity update not sync to frontend
    if (state?.from === 'edit-capacity') {
      fetchCluster(cluster.id)
    }
  }, [state?.from, cluster.id, fetchCluster])

  return (
    <Stack gap="xl" justify="flex-start" px="xl" miw={937}>
      {top}
      <Flex
        gap="xl"
        align="stretch"
        sx={(theme) => ({ [`@media (max-width: ${theme.breakpoints.lg}px)`]: { flexWrap: 'wrap' } })}
      >
        <Box w={'100%'}>
          {cluster.computed.isEssential ? (
            <StandardCapacity
              cluster={cluster}
              miw={448}
              mb={24}
              sx={{ flex: 1, display: 'flex', flexDirection: 'column', justifyContent: 'space-between' }}
            />
          ) : (
            <SpendLimitUsage
              cluster={cluster}
              miw={448}
              mb={24}
              sx={{ flex: 1, display: 'flex', flexDirection: 'column', justifyContent: 'space-between' }}
            />
          )}

          <MonitorCard cluster={cluster} />
        </Box>

        <Box maw={400}>
          {!cluster.computed.isEssential && (
            <>
              {cluster.computed.loading || cluster.computed.isStarter ? (
                <CodeExamplesBasePanel mb={24} />
              ) : (
                <CodeExamplesPanel mb={24} />
              )}
            </>
          )}
          <ServerlessClusterPropPanel
            cluster={cluster}
            miw={400}
            rightSection={<ServicePlanTag servicePlan={cluster.serverless?.servicePlan ?? 'Starter'} />}
            sx={(theme) => ({
              [`@media (max-width: ${theme.breakpoints.lg}px)`]: {
                flex: 1
              }
            })}
          />
        </Box>
      </Flex>
    </Stack>
  )
}

interface ClusterOverviewProps {
  cluster: SharedCluster
  top?: {
    serverless?: React.ReactNode
    dedicated?: React.ReactNode
  }
}

/**
 * Split cluster overview into different ones
 * according to the cluster tier type.
 * It can reduce our mental workload of maintaining
 * features of different tiers.
 */
const ClusterOverview = ({ cluster, top }: ClusterOverviewProps) => {
  const tier = cluster.computed.clusterType

  switch (tier) {
    case 'Dedicated':
      return <DedicatedOverview cluster={cluster} />
    case 'Serverless':
      return <ServerlessOverview cluster={cluster} top={top?.serverless} />
    default:
      return null
  }
}

export default ClusterOverview
