import { Card, Button, Divider, Stack, Flex } from '@tidbcloud/uikit'
import { useMemoizedFn } from 'ahooks'
import { observer } from 'mobx-react'
import { useFormContext } from 'react-hook-form'

import { NodeSpecByType } from 'dbaas/screens/ClustersV2/new/store/helpers'
import { TidbCloudOpenApidedicatedv1beta1Cluster } from 'dbaas/services/api-clients/v2023/cluster-management/v1beta1/interface'
import { getErrorMessage } from 'dbaas/services/errorCodes'

import { HeadLabel } from '../components'
import { FormModelForTidbGroup } from '../helpers'

import { CostPanel } from './CostPanel'
import {
  isNodeSizesChanged,
  isTikvOrTiflashChanged,
  useCancel,
  useModifyDedicatedCluster,
  useModifyingFinished,
  useCheckModificationRisks
} from './helpers'
import { StorageNodesReview } from './StorageNodesReview'
import { SumInfoItem } from './SumInfoItem'
import { TidbNodesReview } from './TidbNodesReview'

interface SumForTidbGroupProps {
  className?: string
  disabled?: boolean
  cluster: TidbCloudOpenApidedicatedv1beta1Cluster
  clusterSpecs: NodeSpecByType[]
}

export const SumForTidbGroup = observer(({ className, disabled, cluster, clusterSpecs }: SumForTidbGroupProps) => {
  const { clusterId = '', cloudProvider: provider = '', regionId } = cluster
  const {
    watch,
    handleSubmit,
    formState: { errors }
  } = useFormContext<FormModelForTidbGroup>()
  const formErrors = errors.nodes

  const nodes = watch('nodes') || {}
  const isChanged = isNodeSizesChanged(nodes, {
    tidb: cluster.tidbNodeSetting,
    tikv: cluster.tikvNodeSetting,
    tiflash: cluster.tiflashNodeSetting
  })

  const isTikvValueChanged = isTikvOrTiflashChanged('tikv', nodes, { tikv: cluster.tikvNodeSetting })
  const { modifyCluster, isModifying, error: modifyMutationError } = useModifyDedicatedCluster(clusterId)
  const finishModifying = useModifyingFinished(clusterId)

  const { getModifyRisks, isCheckingModifyRisks, error: modifyRiskError } = useCheckModificationRisks(clusterId)
  const modifyError = getErrorMessage(modifyMutationError || modifyRiskError)

  const onSubmit = useMemoizedFn(async (data: FormModelForTidbGroup) => {
    const { nodes } = data || {}

    const { errorMsg } = await modifyCluster({ nodes })

    if (!errorMsg) {
      finishModifying()
    }
  })

  const modifyClusterPrecheck = async (data: FormModelForTidbGroup) => {
    const { nodes } = data
    if (isTikvValueChanged) {
      const { errorMsg } = await getModifyRisks(nodes)
      if (errorMsg) {
        return
      }
    }

    onConfirm()
  }

  const onConfirm = handleSubmit(onSubmit)
  const onModifyClusterPrecheck = handleSubmit(modifyClusterPrecheck)
  const onCancel = useCancel()

  return (
    <Card className={className} shadow="none" p="xl">
      <HeadLabel label="Summary" description="Your cluster will be:" />
      <Stack justify="flex-start" gap="md" py="xl" sx={{ position: 'relative' }}>
        <SumInfoItem label="Name" value={cluster.displayName} />
      </Stack>
      <Divider color="carbon.4" />
      <Stack justify="flex-start" gap="md" py="xl" sx={{ position: 'relative' }}>
        <SumInfoItem
          label="TiDB"
          value={
            <TidbNodesReview
              clusterSpecs={clusterSpecs}
              origin={cluster.tidbNodeSetting}
              current={nodes.tidb}
              provider={provider}
            />
          }
          isError={!!formErrors?.tidb}
          errors="Invalid Size"
        />
        <SumInfoItem
          label="TiKV"
          value={
            <StorageNodesReview
              clusterSpecs={clusterSpecs}
              component="tikv"
              origin={cluster.tikvNodeSetting}
              current={nodes.tikv}
              provider={provider}
            />
          }
          isError={!!formErrors?.tikv}
          errors="Invalid Size"
        />
        {(!!cluster.tiflashNodeSetting?.nodeCount || !!nodes.tiflash?.nodeCount) && (
          <SumInfoItem
            label="TiFlash"
            value={
              <StorageNodesReview
                clusterSpecs={clusterSpecs}
                component="tiflash"
                origin={cluster.tiflashNodeSetting}
                current={nodes.tiflash}
                provider={provider}
              />
            }
            isError={!!formErrors?.tiflash}
            errors="Invalid Size"
          />
        )}
      </Stack>
      <Divider color="carbon.4" />
      <CostPanel provider={provider} region={regionId?.replace(/^(aws|gcp|azure)-/, '')} modifyError={modifyError} />
      <Flex align="center" gap="md" mt="md">
        <Button
          variant="default"
          onClick={onCancel}
          data-mp-event="Cancel Modify A Cluster"
          data-mp-source="Clusters - Modifying v2"
        >
          Cancel
        </Button>
        <Button
          disabled={disabled || !isChanged}
          loading={isModifying || isCheckingModifyRisks}
          onClick={onModifyClusterPrecheck}
          sx={{ flexGrow: 1 }}
          data-mp-event="Modify Cluster Form Confirm Button Clicked"
          data-mp-source="Clusters - Modifying v2"
        >
          {isChanged ? 'Confirm' : 'No change'}
        </Button>
      </Flex>
    </Card>
  )
})
