import { Alert, Anchor, Group, NumberInput, Stack, StackProps, Typography } from '@tidbcloud/uikit'
import { FormNumberInput } from '@tidbcloud/uikit/biz'
import { IconAlertTriangle, IconInfoCircle } from '@tidbcloud/uikit/icons'
import { useEffect } from 'react'
import { useFormContext } from 'react-hook-form'
import { useQuery } from 'react-query'

import TimeComponent from 'dbaas/components/TimeComponent'
import { useRequestSupport } from 'dbaas/screens/HelpCenter/RequestSupport/helper'
import {
  ESSENTIAL_V2_RCU_MAX,
  ESSENTIAL_V2_RCU_MIN,
  ESSENTIAL_V2_RCU_STEP
} from 'dbaas/screens/NextGen/my-tidb-creation/plans/EssentialV2/schema'
import { useSharedTiDBContext } from 'dbaas/screens/NextGen/tidb-mgmt-container/shared/tidb-context'
import { tidbServiceCalculateMinRcu } 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 { EditFormValueState } from './helpers'

interface EssentialV2CapacityFieldProps extends StackProps {
  formMaxRcuName?: string
  instanceMaxRcu?: number
  availableTotalRcu?: number
  scaleDownCooldownMinutes: number
  showBillingDescription?: boolean
}

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

  return `${minutes} minutes`
}

export const EssentialV2CapacityField = ({
  formMaxRcuName = 'maxRcu',
  instanceMaxRcu,
  availableTotalRcu,
  scaleDownCooldownMinutes,
  showBillingDescription = true,
  ...props
}: EssentialV2CapacityFieldProps) => {
  const tidb = useSharedTiDBContext()
  const { watch, setValue } = useFormContext<EditFormValueState>()
  const maxRcu = watch(formMaxRcuName as 'maxRcu')
  const { open: openSupport } = useRequestSupport()
  const {
    store: {
      tenantData,
      lastVisitLocation: { orgId, projectId }
    }
  } = useStores()

  const { data: minRcu = ESSENTIAL_V2_RCU_MIN } = useQuery(
    ['essential-v2-update-calculate-min-rcu', orgId, projectId, tidb.regionId, maxRcu],
    () =>
      tidbServiceCalculateMinRcu(
        {
          maxRcu: String(maxRcu),
          regionId: tidb.regionId,
          servicePlan: Commonv1beta1ServicePlan.Essential_V2
        },
        { orgId, projectId }
      ),
    {
      refetchOnWindowFocus: false,
      enabled: !!(orgId && projectId && tidb.regionId && maxRcu),
      select: (data) => Number(data?.minRcu || ESSENTIAL_V2_RCU_MIN)
    }
  )

  useEffect(() => {
    setValue('minRcu', Number(minRcu))
  }, [minRcu, setValue])

  const effectiveMaxRcu = Math.min(
    instanceMaxRcu ?? ESSENTIAL_V2_RCU_MAX,
    availableTotalRcu ?? ESSENTIAL_V2_RCU_MAX,
    ESSENTIAL_V2_RCU_MAX
  )
  const capacityUpdateTime = tidb.capacityUpdateTime ? new Date(tidb.capacityUpdateTime) : undefined
  const capacityDecreaseUnlockTime =
    capacityUpdateTime && !Number.isNaN(capacityUpdateTime.getTime())
      ? new Date(capacityUpdateTime.getTime() + scaleDownCooldownMinutes * 60 * 1000)
      : undefined
  const showCapacityDecreaseLockedAlert =
    !!capacityDecreaseUnlockTime && Date.now() < capacityDecreaseUnlockTime.getTime()

  return (
    <Stack gap="lg" {...props}>
      <Group align="flex-start">
        <NumberInput
          name="minimumRCU"
          value={minRcu}
          disabled
          leftAddon="Minimum Billing RCU"
          suffix=" RCUs"
          flex={1}
          step={ESSENTIAL_V2_RCU_STEP}
        />
        <FormNumberInput
          name={formMaxRcuName}
          leftAddon="Max"
          suffix=" RCUs"
          flex={1}
          min={ESSENTIAL_V2_RCU_MIN}
          max={effectiveMaxRcu}
          step={ESSENTIAL_V2_RCU_STEP}
          rules={{
            required: 'Required',
            min: {
              value: ESSENTIAL_V2_RCU_MIN,
              message: `Value must be at least ${ESSENTIAL_V2_RCU_MIN}`
            },
            max: { value: effectiveMaxRcu, message: `Value cannot exceed ${effectiveMaxRcu}` },
            validate: (val) => {
              if (val % ESSENTIAL_V2_RCU_STEP !== 0) {
                return `Value must be in increments of ${ESSENTIAL_V2_RCU_STEP}`
              }

              if (instanceMaxRcu !== undefined && val > instanceMaxRcu) {
                return `Max RCU cannot exceed the single instance limit of ${instanceMaxRcu}`
              }

              if (availableTotalRcu !== undefined && val > availableTotalRcu) {
                return `Max RCU would exceed the total limit. Available: ${availableTotalRcu} RCUs`
              }

              return true
            }
          }}
        />
      </Group>
      {showBillingDescription && (
        <Typography variant="body-md" c="carbon.7">
          Minimum Billing RCU is automatically set based on your Maximum RCU value. If your actual usage falls below
          this threshold, you will be billed for the minimum amount to cover the cost of reserved resources.
        </Typography>
      )}
      {showCapacityDecreaseLockedAlert && (
        <Alert color="yellow" icon={<IconAlertTriangle size={14} />}>
          Scale-down is currently unavailable. You will be able to decrease the capacity limit after{' '}
          <Typography component="span" fw={600}>
            <TimeComponent
              time={capacityDecreaseUnlockTime!}
              format="YYYY-MM-DD, HH:mm:ss"
              utcOffset={tenantData.timezone}
            />
          </Typography>
          . In case of an emergency during the lockdown period, please contact{' '}
          <Anchor component="button" type="button" onClick={() => openSupport()}>
            TiDB Cloud Support
          </Anchor>
          .
        </Alert>
      )}
      <Alert color="peacock" icon={<IconInfoCircle size={14} />}>
        Maximum RCU increases are unrestricted. However, a {formatCooldownDuration(scaleDownCooldownMinutes)} cooldown
        period is required after any change before the Maximum RCU can be decreased again.
      </Alert>
    </Stack>
  )
}
