import { Box, Loader } from '@tidbcloud/uikit'
import { FormNumberInput } from '@tidbcloud/uikit/biz'
import { useEffect, useRef } from 'react'
import { useFormContext } from 'react-hook-form'

import { FormItem } from 'dbaas/screens/NextGen/my-tidb-creation/shared/FormItem'
import { useGetPricingDetails } from 'dbaas/services/api-clients/legacy/serverless'

import { SpendLimitInputDesc } from '../spend-limit/SpendLimitInputDesc'
import { useSpendLimitFreeQuota } from '../spend-limit/use-spend-limit-free-quota'
import { StarterFormValue } from '../types'

interface SpendingLimitSectionProps {
  projectId: string
  disabled?: boolean
}

export function SpendingLimitSection({ projectId, disabled }: SpendingLimitSectionProps) {
  const {
    register,
    watch,
    getValues,
    setValue,
    trigger,
    formState: { errors }
  } = useFormContext<StarterFormValue>()

  const provider = watch('provider')
  const region = watch('region')
  const spendingLimit = watch('spendingLimit')
  const encrypted = watch('encrypted')

  const {
    exhausted,
    maxFreeCount,
    isLoading: freeQuotaLoading,
    isSuccess: freeQuotaSuccess
  } = useSpendLimitFreeQuota({
    projectId
  })
  const pricingQuery = useGetPricingDetails(
    { region, cloud_provider: provider },
    { query: { enabled: !!(provider && region), refetchOnWindowFocus: false } }
  )
  const pricingValid = !!(pricingQuery.data?.request_units && pricingQuery.data.row_based_storage)

  useEffect(() => {
    if (exhausted) {
      setValue('spendingLimitMode', 'spendingLimit')
      trigger('spendingLimit')
    }
  }, [exhausted, setValue, trigger])

  const didInitFreeQuotaRef = useRef(false)
  useEffect(() => {
    if (!freeQuotaSuccess || exhausted || didInitFreeQuotaRef.current) {
      return
    }

    didInitFreeQuotaRef.current = true
    setValue('spendingLimit', 0)
    setValue('spendingLimitMode', 'freeQuota')
  }, [exhausted, freeQuotaSuccess, setValue])

  useEffect(() => {
    const currentMode = getValues('spendingLimitMode')
    if (exhausted && currentMode !== 'spendingLimit') {
      setValue('spendingLimitMode', 'spendingLimit')
    }
  }, [exhausted, getValues, setValue])

  return (
    <FormItem
      label="Capacity"
      description={
        <>
          Capacity scales automatically based on your workload, and you only pay for what you use. Each organization can
          have up to {maxFreeCount} free TiDB Cloud Starter instances, each with 5GiB Row-based Storage and 50M Request
          Units.{' '}
          {pricingValid
            ? `Additional resources are priced at ${pricingQuery.data?.row_based_storage} Row-based Storage and ${pricingQuery.data?.request_units} Request Units. `
            : null}
          <a href="https://www.pingcap.com/tidb-serverless-pricing-details/" target="_blank" rel="noreferrer">
            Learn more
          </a>
          .
        </>
      }
    >
      <input type="hidden" {...register('spendingLimitMode')} />
      <FormNumberInput
        name="spendingLimit"
        fixedDecimalScale
        decimalScale={2}
        min={exhausted ? 0.01 : 0}
        disabled={disabled || freeQuotaLoading}
        label="Monthly Spending Limit"
        rightSection={freeQuotaLoading ? <Loader size="xs" /> : undefined}
        leftSection={
          <Box c={errors?.spendingLimit ? 'red' : 'carbon.8'} fz={14} w={16} ta="right">
            $
          </Box>
        }
        leftSectionWidth={28}
        rules={{
          pattern: {
            value: /^\d+$|^\d+\.\d{0,2}$/,
            message: 'Please enter an integer or a number with two decimal places.'
          },
          min: exhausted
            ? { value: 0.01, message: 'The spending limit must be greater than or equal to $0.01' }
            : undefined,
          required: exhausted
            ? {
                value: true,
                message: 'The free quota of your organization is exhausted. Please set the spending limit.'
              }
            : undefined
        }}
        onChange={(value) => {
          const fixedValue = Number(value ?? 0)

          if (exhausted) {
            setValue('spendingLimitMode', 'spendingLimit')
            return
          }

          if (fixedValue > 0) {
            setValue('spendingLimitMode', 'spendingLimit')
          } else {
            setValue('spendingLimitMode', 'freeQuota')
          }
        }}
      />
      {!errors?.spendingLimit && (
        <SpendLimitInputDesc
          projectId={projectId}
          value={spendingLimit}
          region={region}
          encrypted={encrypted}
          resourceName="instance"
          mt={8}
        />
      )}
    </FormItem>
  )
}
