import { AnimatedNumber, Card, Divider, Flex, Skeleton, Stack, Typography } from '@tidbcloud/uikit'
import { useDebouncedValue } from '@tidbcloud/uikit/hooks'
import { observer } from 'mobx-react'
import { useMemo } from 'react'
import { useFormContext } from 'react-hook-form'

import { getCloudProviderLabel } from 'dbaas/features/Project'
import { HeadLabel, SumInfoItem } from 'dbaas/screens/ClustersV2/new/components'
import { HADescriptions } from 'dbaas/screens/ClustersV2/new/Serverless/FormContent/AdvancedSettings'
import { usePredictCost } from 'dbaas/services/api-clients/legacy/serverless'
import { Commonv1beta1ServicePlan } from 'dbaas/services/api-clients/v2023/serverless/v1beta1/interface'

import { CancelButton } from '../components/CancelButton'
import { CreateButton } from '../components/CreateButton'
import { CreditAdd } from '../components/CreditAdd'

import { useEssentialFormStore, useAddCreditCard, ESSENTIAL_RCU_MIN } from './helper'

import { EssentialFormValue } from './index'

interface SumCardProps {
  className?: string
  disabled?: boolean
  onCancel: () => void
}

export const EssentialSummary = ({
  isLoading,
  provider,
  regionName,
  name,
  encrypted,
  highAvailabilityType,
  errors,
  predictCost
}: {
  isLoading: boolean
  provider: string
  regionName: string
  name: string
  errors: any
  encrypted: boolean
  highAvailabilityType: string
  predictCost?: {
    hourly?: number
    monthly?: number
  }
}) => {
  return (
    <>
      <Stack justify="flex-start" gap={8} py="xl">
        <SumInfoItem label="Plan" value="Essential" labelProps={{ w: 144 }} />

        <SumInfoItem
          label="Provider"
          value={isLoading ? <Skeleton width={80} height={16} /> : getCloudProviderLabel(provider)}
          labelProps={{ w: 144 }}
        />

        <SumInfoItem
          label="Region"
          value={isLoading ? <Skeleton width={120} height={16} /> : regionName}
          labelProps={{ w: 144 }}
        />

        <SumInfoItem
          label="Name"
          value={isLoading ? <Skeleton width={100} height={16} /> : name}
          isError={!!errors?.name}
          labelProps={{ w: 144 }}
        />

        <SumInfoItem
          label="Dual-Layer Data Encryption"
          value={isLoading ? <Skeleton width={100} height={16} /> : encrypted ? 'Enabled' : 'Disabled'}
          labelProps={{ w: 144 }}
        />

        <SumInfoItem
          label="High Availability"
          value={isLoading ? <Skeleton width={100} height={16} /> : HADescriptions[highAvailabilityType]}
          isError={!!errors?.name}
          labelProps={{ w: 144 }}
        />
      </Stack>

      <Divider />

      <Stack gap={4} py="xl">
        <AnimatedNumber
          value={predictCost?.monthly ?? 0}
          format={{ maximumFractionDigits: 5, minimumFractionDigits: 2 }}
          prefix="From $"
          suffix="/month"
          c="carbon.9"
          fw={700}
          fz={20}
          sx={{
            '&::part(suffix)': {
              color: 'var(--mantine-color-carbon-8)',
              fontWeight: 400,
              fontSize: 14,
              marginLeft: 4
            }
          }}
        />
        <Typography variant="body-lg" c="carbon.7">
          Learn more about{' '}
          <a target="_blank" rel="noreferrer" href="https://www.pingcap.com/tidb-cloud-essential-pricing-details/">
            TiDB Cloud Essential pricing
          </a>
          .
        </Typography>
      </Stack>
    </>
  )
}

export const EssentialSummaryCard = observer(({ className, disabled, onCancel }: SumCardProps) => {
  const {
    watch,
    formState: { errors }
  } = useFormContext<EssentialFormValue>()
  const provider = watch('provider')
  const region = watch('region')
  const name = watch('name')
  const minRcu = watch('autoScaling.minRcu')
  const encrypted = watch('encrypted')
  const highAvailabilityType = watch('highAvailabilityType')
  const [debouncedMinRcu] = useDebouncedValue(minRcu, 500)
  const { regions, isLoading } = useEssentialFormStore(provider, 'Essential')

  const predictRcu = Math.max(debouncedMinRcu || ESSENTIAL_RCU_MIN, ESSENTIAL_RCU_MIN)
  const {
    data: predictCost
    // isFetching: isPredictCostFetching
  } = usePredictCost(
    {
      cloud_provider: provider,
      region: region,
      rcu: predictRcu
    },
    {
      query: {
        enabled: !!(provider && region),
        select: (data) => {
          const monthly = Number(data?.rcu_cost_monthly || 0)
          const hourly = Number(data?.rcu_cost_hourly || 0)

          return {
            monthly,
            hourly
          }
        },
        keepPreviousData: true,
        refetchOnWindowFocus: false
      }
    }
  )

  const regionName = useMemo(() => {
    return regions?.find((item) => item.name === region)?.displayName ?? ''
  }, [region, regions])

  return (
    <Card className={className} p="xl" sx={{ position: 'sticky', top: 'var(--app-page-shell-header-height)' }}>
      <HeadLabel label="Summary" description="Your new cluster will be:" />

      <EssentialSummary
        // todo: at preview stage, the cost is free
        // isLoading={isLoading || isPredictCostFetching || isPredictCostLoading}
        isLoading={isLoading}
        provider={provider}
        regionName={regionName}
        name={name}
        errors={errors}
        predictCost={predictCost}
        encrypted={encrypted}
        highAvailabilityType={highAvailabilityType}
      />

      <EssentialActions
        onCancel={onCancel}
        disabled={disabled}
        // todo: at preview stage, the cost is free
        // loading={isLoading || isPredictCostFetching || isPredictCostLoading}
        // buttonText={
        //   isPredictCostFetching || isPredictCostLoading ? 'Calculating...' : isLoading ? 'Fetching...' : 'Create'
        // }
        loading={isLoading}
        buttonText={isLoading ? 'Fetching...' : 'Create'}
      />
    </Card>
  )
})

const EssentialActions = ({
  onCancel,
  loading,
  disabled,
  buttonText
}: {
  onCancel: () => void
  loading?: boolean
  disabled?: boolean
  buttonText?: string
}) => {
  const { creditAddVisible, creditModalVisible, creditModalHandlers } = useAddCreditCard()
  const {
    formState: { errors }
  } = useFormContext<EssentialFormValue>()
  const isFormError = !!Object.keys(errors).length

  return (
    <Flex align="center" gap="md">
      <CancelButton onCancel={onCancel} servicePlan={Commonv1beta1ServicePlan.Essential} />

      {!loading && creditAddVisible ? (
        <CreditAdd
          disabled={disabled || isFormError}
          creditAddVisible={true}
          creditModalVisible={creditModalVisible}
          creditModalHandlers={creditModalHandlers}
        />
      ) : (
        <CreateButton
          loading={loading}
          disabled={disabled || isFormError}
          type={Commonv1beta1ServicePlan.Essential}
          buttonText={buttonText}
        />
      )}
    </Flex>
  )
}
