import { Box, Group, Stack, Typography } from '@tidbcloud/uikit'
import { Fragment, useMemo } from 'react'

import { renderNodes } from 'dbaas/features/ClusterManagement/common'
import { renderTiproxy } from 'dbaas/features/ClusterManagement/dedicated/node/NodeSizes/TiProxy'
import { WaringForSpecInSummary } from 'dbaas/features/ClusterManagement/dedicated/node/NodeSizes/WarningForSpecInSummary'
import { renderSpecVersion, useSpecVersionEnabled } from 'dbaas/screens/Cluster/OverviewV2/helpers'
import { NodeSpecByType } from 'dbaas/screens/ClustersV2/new/store/helpers'
import { V1beta1ClusterTidbNodeSetting } from 'dbaas/services/api-clients/v2023/cluster-management/v1beta1/interface'
import { Dedicatedv1beta1ComponentType } from 'dbaas/services/api-clients/v2023/dedicated/v1beta1/interface'

import { FormModelForTidbGroup } from '../helpers'

interface TidbNodesReviewProps {
  clusterSpecs: NodeSpecByType[]
  origin: V1beta1ClusterTidbNodeSetting
  current: FormModelForTidbGroup['nodes']['tidb']
  provider: string
}

export const TidbNodesReview = ({ clusterSpecs, origin, current, provider }: TidbNodesReviewProps) => {
  const { specVersionEnabled } = useSpecVersionEnabled(provider)

  const { spec, specName } = useMemo(() => {
    const compSpecs = clusterSpecs?.find((item) => item.componentType === Dedicatedv1beta1ComponentType.TIDB)?.nodeSpecs
    const spec = compSpecs?.find((item) => item.nodeSpecKey === current.specKey)
    const specName = `${spec?.displayName ?? ''}${renderSpecVersion(spec?.version, specVersionEnabled)}`

    return {
      spec,
      specName
    }
  }, [current.specKey, clusterSpecs])

  /**
   * | origin | current | origin display  | current display |
   * | ------ | ------- | --------------- | --------------- |
   * | ❌     | ❌       | no              | no              |
   * | ❌     | ✅       | no              | bold            |
   * | ✅     | ✅       | normal          | no              |
   * | ✅     | ❌       | line-through    | no              |
   * | ✅     | 🆕       | line-through    | bold            |
   */

  return (
    <Stack justify="flex-start" gap={8}>
      {/* vCPU + RAM */}
      {!!origin.nodeSpecKey && (
        <Group gap={4}>
          <Typography variant="body-lg" td={current.specKey !== origin.nodeSpecKey ? 'line-through' : undefined}>
            {origin.nodeSpecDisplayName}
            {renderSpecVersion(origin.nodeSpecVersion, specVersionEnabled)}
          </Typography>
          <WaringForSpecInSummary cpuNum={spec?.vCpu ?? 0} memory={spec?.memorySizeGi ?? 0} />
        </Group>
      )}
      {!!current.specKey && current.specKey !== origin.nodeSpecKey && (
        <Group>
          <Typography variant="label-lg">{specName}</Typography>
        </Group>
      )}

      {/* TiDB node groups */}
      {origin.tidbNodeGroups?.map((item) => {
        const currentGroup = current.nodeGroups?.find((group) => group.groupId === item.tidbNodeGroupId)
        const different = currentGroup?.nodeCount !== item.nodeCount || currentGroup?.editMode === 'delete'
        const tiproxyDifferent =
          currentGroup?.tiproxySetting?.nodeCount !== item.tiproxySetting?.nodeCount ||
          currentGroup?.tiproxySetting?.nodeSpecKey !== item.tiproxySetting?.nodeSpecKey

        return (
          <Fragment key={item.tidbNodeGroupId}>
            <Group gap={4}>
              <Typography variant="body-lg" truncate maw={136} td={different ? 'line-through' : undefined}>
                {item.displayName}
              </Typography>
              x
              <Typography variant="body-lg" td={different ? 'line-through' : undefined}>
                {renderNodes(item.nodeCount)}
              </Typography>
            </Group>
            {!!currentGroup && different && currentGroup.editMode !== 'delete' && (
              <Group gap={4}>
                <Typography variant="label-lg" truncate maw={136}>
                  {currentGroup.displayName}
                </Typography>
                x<Typography variant="label-lg">{renderNodes(currentGroup.nodeCount ?? 0)}</Typography>
              </Group>
            )}
            {renderTiproxy(item.tiproxySetting, tiproxyDifferent)}
            {tiproxyDifferent && renderTiproxy(currentGroup?.tiproxySetting)}
          </Fragment>
        )
      })}
      {current.nodeGroups
        ?.filter((g) => g.editMode === 'add')
        ?.map((g, index) => (
          <>
            <Group key={`new-group-${index}`} gap={4}>
              <Typography variant="label-lg" truncate maw={136}>
                {g.displayName}
              </Typography>
              <Box>:</Box>
              <Typography variant="label-lg">{renderNodes(g.nodeCount ?? 0)}</Typography>
            </Group>
            {renderTiproxy(g?.tiproxySetting)}
          </>
        ))}
    </Stack>
  )
}
