import { Box, Loader, Skeleton, Stack, Typography } from '@tidbcloud/uikit'
import { FormNumberInput } from '@tidbcloud/uikit/biz'
import { useMemoizedFn } from 'ahooks'
import { observer } from 'mobx-react'
import { useFormContext } from 'react-hook-form'

import { SharedCluster } from 'dbaas/features/ClusterManagement/cluster'
import { SpendLimitInputDesc, useSpendLimitFreeQuota } from 'dbaas/features/ClusterManagement/serverless'
import { ClusterPlanSelector } from 'dbaas/features/ClusterManagement/serverless'
import { useRequestSupport } from 'dbaas/screens/HelpCenter/RequestSupport/helper'
import { useGetClusterSpendLimit } from 'dbaas/services/api'
import { useGetPricingDetails } from 'dbaas/services/api-clients/legacy/serverless'
import useStores from 'dbaas/stores/useStores'
import { toDollars } from 'dbaas/utils/format'

import { EditFormValueState } from './helpers'
import { SpendEstimation } from './SpendEstimation'

interface ClusterPlanFieldProps {
  cluster: SharedCluster
}

export const ClusterPlanField = observer(({ cluster }: ClusterPlanFieldProps) => {
  const {
    store: {
      lastVisitLocation: { orgId }
    }
  } = useStores()
  const { open: wakeUpSupport } = useRequestSupport()
  const { id: clusterId, region } = cluster

  const {
    watch,
    setValue,

    formState: { errors }
  } = useFormContext<EditFormValueState>()
  const formValues = watch() || {}
  const { plan, monthlySpendingLimit } = formValues
  const isError = !!errors?.monthlySpendingLimit
  const isScalablePlan = plan === 'scalable'

  const spendingLimitQuery = useGetClusterSpendLimit(orgId, clusterId, {
    query: {
      refetchOnWindowFocus: false,
      onSuccess(data) {
        if (data.spend_limit > 0) {
          setValue('monthlySpendingLimit', toDollars(data.spend_limit))
        }
      }
    }
  })
  const savedSpendingLimit = toDollars(spendingLimitQuery.data?.spend_limit || 0)
  const savedPlan = !!(spendingLimitQuery.isFetchedAfterMount && spendingLimitQuery.isSuccess)
    ? !!spendingLimitQuery.data?.spend_limit
      ? 'scalable'
      : 'free'
    : ''

  const pricingQuery = useGetPricingDetails(
    { region, cloud_provider: cluster.provider },
    {
      query: {
        enabled: !!region
      }
    }
  )
  const pricingValid = !!(pricingQuery.data?.request_units && pricingQuery.data.row_based_storage)
  const { exhausted, maxFreeCount } = useSpendLimitFreeQuota()

  const onPlanChange = useMemoizedFn((val: EditFormValueState['plan']) => {
    if (val === 'scalable') {
      setValue('monthlySpendingLimit', savedSpendingLimit || 1)
    } else {
      setValue('monthlySpendingLimit', 0)
    }
  })

  return (
    <Stack gap="md">
      <Box>
        <Typography variant="title-lg">Instance Plan</Typography>
        <Typography variant="body-lg" mt={4}>
          {exhausted
            ? `You have already created ${maxFreeCount} instances with free quota.`
            : `Start with ${maxFreeCount} free instances, each with 5GiB storage and 50M request units.`}{' '}
          Opt for scalable clusters to unlock enhanced performance.{' '}
          {pricingValid &&
            `Further resources are priced at ${pricingQuery.data?.row_based_storage}
            storage and ${pricingQuery.data?.request_units} Request Units.`}{' '}
          Learn more about{' '}
          <a
            href="https://www.pingcap.com/tidb-serverless-pricing-details/"
            target="_blank"
            rel="noreferrer"
            onClick={(e) => e.stopPropagation()}
          >
            Serverless Pricing
          </a>
          .
        </Typography>
      </Box>
      <ClusterPlanSelector
        name="plan"
        plans={{
          free: {
            desc: spendingLimitQuery.isFetching ? (
              <Stack gap={8} mt={4}>
                <Skeleton height={14} radius="sm" />
                <Skeleton height={14} radius="sm" />
              </Stack>
            ) : savedPlan === 'scalable' ? (
              <>
                If you need to downgrade your current plan to Free Cluster, please{' '}
                <Box
                  component="a"
                  onClick={(e: React.MouseEvent<HTMLAnchorElement>) => {
                    e?.preventDefault()
                    e?.stopPropagation()
                    wakeUpSupport({
                      orgId,
                      cluster,
                      subject: 'Request to downgrade to Free Cluster'
                    })
                  }}
                >
                  contact our support
                </Box>
                .
              </>
            ) : (
              'No credit card required. Includes 5GiB storage and 50M request units. Ideal for small-scale applications. You can upgrade to a scalable instance any time.'
            ),
            badge: savedPlan === 'free' ? 'Current' : undefined,
            disabled: exhausted || savedPlan === 'scalable' || spendingLimitQuery.isFetching,
            tooltip:
              !spendingLimitQuery.isFetching && exhausted
                ? `You have already reached the limit of ${maxFreeCount} free instances.`
                : undefined
          },
          scalable: {
            desc: spendingLimitQuery.isFetching ? (
              <Stack gap={8} mt={4}>
                <Skeleton height={14} radius="sm" />
                <Skeleton height={14} radius="sm" />
              </Stack>
            ) : (
              'All benefits of Free Cluster plus expandable storage and request units. Seamlessly scales compute resources to meet workload demands. Optional advanced features include enhanced encryption at rest and regional high availability (HA). Credit card required.'
            ),
            badge: savedPlan === 'scalable' ? 'Current' : undefined,
            disabled: spendingLimitQuery.isFetching
          }
        }}
        onChange={onPlanChange}
      />
      <Box display={isScalablePlan ? undefined : 'none'}>
        <FormNumberInput
          name="monthlySpendingLimit"
          label="Monthly Spending Limit"
          leftSection={
            <Box c={isError ? 'red' : 'carbon.8'} fz={14} w={16} ta="right">
              $
            </Box>
          }
          leftSectionWidth={28}
          disabled={spendingLimitQuery.isFetching}
          rightSection={spendingLimitQuery.isFetching ? <Loader size="xs" /> : undefined}
          fixedDecimalScale
          decimalScale={2}
          min={isScalablePlan ? 0.01 : 0}
          rules={{
            pattern: {
              value: /^\d+$|^\d+\.\d{0,2}$/,
              message: 'Please enter an integer or a number with two decimal places.'
            },
            ...(isScalablePlan
              ? {
                  min: {
                    value: 0.01,
                    message: 'The spending limit must be greater than or equal to $0.01'
                  }
                }
              : {})
          }}
          styles={{ control: { cursor: 'pointer', ':disabled': { cursor: 'not-allowed' } } }}
        />
        {!isError && <SpendLimitInputDesc value={monthlySpendingLimit} region={region} clusterId={clusterId} mt={8} />}
      </Box>
      <SpendEstimation cluster={cluster} />
    </Stack>
  )
})
