import {
  Alert,
  Button,
  Card,
  Flex,
  Stack,
  Typography,
  TypographyProps,
  notifier,
  openConfirmModal
} from '@tidbcloud/uikit'
import { IconInfoCircle } from '@tidbcloud/uikit/icons'
import { useMemoizedFn } from 'ahooks'
import { observer } from 'mobx-react'
import { useFormContext } from 'react-hook-form'
import { useHistory } from 'react-router-dom'

import { PropertyKV } from 'dbaas/components'
import { getApiErrorMsgDom } from 'dbaas/components/Notification/ErrorMessag'
import { getCloudProviderLabel } from 'dbaas/features/Project'
import { queryClient } from 'dbaas/reactQueryClient'
import { EssentialV2Cost } from 'dbaas/screens/NextGen/my-tidb-creation/plans/EssentialV2/summary/EssentialV2Cost'
import { SharedTiDB } from 'dbaas/screens/NextGen/shared/model/shared-tidb-state'
import { getDisplayServicePlan } from 'dbaas/screens/NextGen/shared/tidb-instance/service-plan/ServicePlanTag'
import { getTiDBServiceGetTidbQueryKey } from 'dbaas/services/api-clients/v2023/cluster-management/v1beta2'
import {
  getTidbServiceGetTidbQueryKey,
  useTidbServiceUpdateTidb
} from 'dbaas/services/api-clients/v2025/tidb-management/v1beta2'
import { Commonv1beta1ServicePlan } from 'dbaas/services/api-clients/v2025/tidb-management/v1beta2/interface'
import useStores from 'dbaas/stores/useStores'
import { MixpanelEvents } from 'dbaas/utils/tracking'

import { EditFormValueState, useCancel } from './helpers'
import {
  invalidateEssentialV2CapacityLimitsQueries,
  useEssentialV2CapacityLimits
} from './use-essential-v2-capacity-limits'

interface EssentialV2SumInfoItemProps {
  label: string
  value?: React.ReactNode
  isError?: boolean
  errors?: React.ReactNode
  labelProps?: TypographyProps
}

export const EssentialV2SumInfoItem = ({
  label,
  value = '',
  isError,
  errors,
  labelProps = {}
}: EssentialV2SumInfoItemProps) => {
  return (
    <PropertyKV
      label={label}
      labelProps={{
        w: 112,
        ...labelProps
      }}
      valueProps={{ color: isError ? 'red' : 'carbon.8' }}
    >
      {isError ? (errors ?? `Invalid ${label}`) : value}
    </PropertyKV>
  )
}

interface EssentialV2SumCardProps {
  tidb: SharedTiDB
  disabled?: boolean
}

const formatCooldownDuration = (minutes: number) => {
  if (minutes % 60 === 0) {
    const hours = minutes / 60
    return `${hours} ${hours === 1 ? 'hour' : 'hours'}`
  }

  return `${minutes} minutes`
}

export const EssentialV2SumCard = observer(({ tidb, disabled }: EssentialV2SumCardProps) => {
  const planLabel = tidb.computed.isCassandra ? 'Cassandra Integration' : getDisplayServicePlan(tidb.servicePlan)
  const {
    store: {
      lastVisitLocation: { orgId, projectId }
    }
  } = useStores()
  const cancel = useCancel()
  const history = useHistory()
  const { scaleDownCooldownMinutes } = useEssentialV2CapacityLimits({
    excludeTidbId: tidb.tidbId,
    projectId: tidb.computed.projectId
  })
  const {
    handleSubmit,
    watch,
    formState: { errors }
  } = useFormContext<EditFormValueState>()
  const minRcu = watch('minRcu')
  const maxRcu = watch('maxRcu')
  const currentMaxRcu = Number(tidb.maxRcu)
  const targetMaxRcu = Number(maxRcu)
  const isMaxRcuChanged =
    Number.isFinite(currentMaxRcu) && Number.isFinite(targetMaxRcu) && targetMaxRcu !== currentMaxRcu

  const updator = useTidbServiceUpdateTidb({
    mutation: {
      onSuccess: async () => {
        if (tidb.tidbId) {
          const v2023QueryKey = getTiDBServiceGetTidbQueryKey(tidb.tidbId || '', { orgId })
          const v2025QueryKey = getTidbServiceGetTidbQueryKey(tidb.tidbId || '', { orgId, projectId })

          notifier.success('Capacity updated successfully!')
          await Promise.all([
            queryClient.refetchQueries(v2023QueryKey, { exact: true }),
            queryClient.invalidateQueries(v2025QueryKey),
            invalidateEssentialV2CapacityLimitsQueries(queryClient, orgId, projectId)
          ])
          history.push(`/tidbs/${tidb.tidbId}/overview`)
        }
      },
      onError: (error) => {
        const errorMsgDom = getApiErrorMsgDom(error)

        notifier.error(errorMsgDom)
      }
    }
  })

  const confirmCapacityUpdate = useMemoizedFn(async () => {
    return await new Promise<boolean>((resolve) => {
      openConfirmModal({
        title: 'Confirm Capacity Update',
        centered: true,
        size: 640,
        trapFocus: false,
        labels: {
          confirm: 'Confirm',
          cancel: 'Cancel'
        },
        children: (
          <Stack gap="lg">
            <Typography variant="body-lg">
              You are about to update your Max RCU. This action will trigger backend resource updates.
            </Typography>
            <Alert color="peacock" icon={<IconInfoCircle size={14} />}>
              Once this change is applied, you will be unable to lower the capacity again for the next{' '}
              {formatCooldownDuration(scaleDownCooldownMinutes)}. Capacity increases will remain available at any time.
            </Alert>
            <Typography variant="body-lg">Are you sure you want to update the Max RCU?</Typography>
          </Stack>
        ),
        onCancel: () => resolve(false),
        onConfirm: () => resolve(true)
      })
    })
  })

  const onSubmit = useMemoizedFn(async (data: EditFormValueState) => {
    if (!orgId || !tidb?.tidbId) {
      notifier.error(<div dangerouslySetInnerHTML={{ __html: 'Failed to update Cluster Plan' }}></div>)
      return
    }

    const originMaxRcu = Number.parseFloat(tidb.maxRcu || '0')
    const targetMaxRcu = Number(data.maxRcu)
    const isMaxRcuChanged = targetMaxRcu !== originMaxRcu
    if (isMaxRcuChanged) {
      const confirmed = await confirmCapacityUpdate()
      if (!confirmed) {
        return
      }
    }

    return await updator.mutateAsync({
      tidbId: tidb.tidbId,
      data: {
        maxRcu: data.maxRcu.toString()
      },
      params: {
        orgId,
        projectId
      }
    })
  })

  const onConfirm = handleSubmit(onSubmit)

  return (
    <Card shadow="none" p="xl" miw={400}>
      <Typography variant="title-lg">Summary</Typography>
      <Typography variant="body-lg" c="carbon.7" mt={4}>
        Your new plan will be
      </Typography>

      <Stack justify="flex-start" gap={8} pt="xl">
        <EssentialV2SumInfoItem label="Plan" value={planLabel} />
        <EssentialV2SumInfoItem label="Provider" value={getCloudProviderLabel(tidb.cloudProvider)} />
        <EssentialV2SumInfoItem label="Region" value={tidb.regionDisplayName} />
        <EssentialV2SumInfoItem label="Name" value={tidb.displayName} />
      </Stack>
      <EssentialV2Cost
        cloudProvider={tidb.cloudProvider ?? ''}
        regionId={tidb.regionId ?? ''}
        minRcu={minRcu ?? 0}
        maxRcu={maxRcu ?? 0}
      />
      <Flex align="center" gap="md">
        <Button
          variant="default"
          onClick={cancel}
          data-mp-event={MixpanelEvents.TidbCapacity.Update.CancelClicked}
          data-mp-service-plan={Commonv1beta1ServicePlan.Essential_V2}
        >
          Cancel
        </Button>
        <Button
          disabled={disabled || !!errors?.maxRcu || !isMaxRcuChanged}
          loading={updator.isLoading}
          onClick={onConfirm}
          sx={{ flexGrow: 1 }}
          data-mp-event={MixpanelEvents.TidbCapacity.Update.SubmitClicked}
          data-mp-service-plan={Commonv1beta1ServicePlan.Essential_V2}
        >
          Update Capacity
        </Button>
      </Flex>
    </Card>
  )
})
