import { notifier, Skeleton } from '@tidbcloud/uikit'
import { Card, Button, Divider, Stack, Flex, Tooltip, Box, CardProps } from '@tidbcloud/uikit'
import { useMemoizedFn } from 'ahooks'
import { camelCase, upperFirst } from 'lodash-es'
import { observer } from 'mobx-react'
import { useMemo } from 'react'
import { useFormContext } from 'react-hook-form'

import { AccessGuard } from 'dbaas/contexts/access-control'
import { getCloudProviderLabel } from 'dbaas/features/Project'
import { useGetRegionsV2 } from 'dbaas/screens/ClustersV2/new/Serverless/helpers'
import { PaymentMethodModal } from 'dbaas/screens/Stripe'
import { Commonv1beta1ServicePlan } from 'dbaas/services/api-clients/v2023/cluster-management/v1beta1/interface'

import { HeadLabel, SumInfoItem } from '../../components'
import { CreationFormValueState } from '../../helpers'
import { useCreateEssentialCluster, useCreationFinished } from '../shared/create-essential'
import { useAddCreditCard } from '../shared/credit-card'

import { EssentialCost } from './EssentialCost'

interface SumCardProps {
  disabled?: boolean
  onCancel?: () => void
  cardProps?: CardProps
}

export const SumCardForEssential = observer(({ onCancel, disabled, cardProps }: SumCardProps) => {
  const {
    watch,
    handleSubmit,
    formState: { dirtyFields, errors }
  } = useFormContext<CreationFormValueState>()
  const formErrors = errors.essential
  const formDirtyFields = dirtyFields.essential

  const { essential: initializing } = watch('initializing')
  const { provider, region, name, encrypted, highAvailabilityType, minRcu } = watch('essential')

  const { data: allRegions } = useGetRegionsV2({
    args: {
      servicePlan: 'Essential'
    },
    refetchOnMount: false
  })
  const regionName = useMemo(() => {
    return allRegions?.find((item) => item.name === region)?.displayName ?? ''
  }, [region, allRegions])
  const { createCluster, isCreating } = useCreateEssentialCluster()
  const finishCreation = useCreationFinished()

  const onSubmit = useMemoizedFn(async (data: CreationFormValueState) => {
    const { provider, region, name, encrypted, highAvailabilityType, minRcu, maxRcu } = data.essential || {}
    const { clusterId, errorMsg } = await createCluster({
      provider,
      region,
      name,
      minRcu,
      maxRcu,
      encrypted,
      highAvailabilityType
    })

    if (clusterId) {
      finishCreation(clusterId)
    } else if (errorMsg) {
      notifier.error(<div dangerouslySetInnerHTML={{ __html: errorMsg }}></div>)
    }
  })
  const onConfirm = handleSubmit(onSubmit)

  const { creditAddVisible, creditModalVisible, creditModalHandlers } = useAddCreditCard()

  const loading = JSON.parse(initializing) as boolean

  return (
    <Card shadow="none" p="xl" {...cardProps}>
      <HeadLabel label="Summary" description="Your new cluster will be:" />
      <Stack justify="flex-start" gap={8} py="xl">
        <SumInfoItem label="Plan" value="Essential" labelProps={{ w: 144 }} />
        <SumInfoItem
          label="Provider"
          value={loading ? <Skeleton width={80} height={16} /> : getCloudProviderLabel(provider)}
          labelProps={{ w: 144 }}
        />
        <SumInfoItem
          label="Region"
          value={loading ? <Skeleton width={120} height={16} /> : regionName}
          labelProps={{ w: 144 }}
        />
        <SumInfoItem
          label="Name"
          value={loading ? <Skeleton width={100} height={16} /> : name}
          isError={!!formErrors?.name}
          labelProps={{ w: 144 }}
        />
        <SumInfoItem
          label="Dual-Layer Data Encryption"
          value={encrypted ? 'Enabled' : 'Disabled'}
          labelProps={{ w: 144 }}
        />
        {!!highAvailabilityType && (
          <SumInfoItem
            label="High Availability"
            value={upperFirst(camelCase(highAvailabilityType))}
            labelProps={{ w: 144 }}
          />
        )}
      </Stack>
      <Divider />
      <EssentialCost cloudProvider={provider} regionName={regionName} minRcu={minRcu} />
      <Flex align="center" gap="md">
        <Button
          variant="default"
          onClick={onCancel}
          data-mp-event="Cancel Created A Cluster"
          data-mp-service-plan={Commonv1beta1ServicePlan.Essential}
          data-mp-filled-fields={['provider', 'region', 'name'].filter((key) => formDirtyFields?.[key]).join(', ')}
        >
          Cancel
        </Button>
        {!creditAddVisible && (
          <Button
            disabled={disabled}
            loading={isCreating || loading}
            onClick={onConfirm}
            sx={{ flexGrow: 1 }}
            data-mp-event="Cluster Creation Button Clicked"
            data-mp-service-plan={Commonv1beta1ServicePlan.Essential}
            data-testid="essential-cluster-creation-btn"
          >
            {loading ? 'Fetching...' : 'Create'}
          </Button>
        )}
        {creditAddVisible && (
          <AccessGuard
            id="BillingPaymentCreation"
            fallback={
              <Tooltip
                withinPortal
                multiline
                sx={{ flexGrow: 1, maxWidth: 320 }}
                label="Please contact the Owner or Billing Manager to add a credit card and your discount will be applied to your next billing cycle."
              >
                <Box>
                  <Button disabled data-mp-event="mp-addcreditcard-1691461017771">
                    Add Credit Card
                  </Button>
                </Box>
              </Tooltip>
            }
          >
            <Button
              disabled={disabled || loading}
              onClick={creditModalHandlers.open}
              sx={{ flexGrow: 1 }}
              data-mp-event="Add Credit Card Button Clicked"
              data-mp-service-plan={Commonv1beta1ServicePlan.Essential}
            >
              Add Credit Card
            </Button>
          </AccessGuard>
        )}
      </Flex>
      {creditAddVisible && (
        <PaymentMethodModal
          open={creditModalVisible}
          onClose={creditModalHandlers.close}
          onComplete={() => {
            creditModalHandlers.close()
            notifier.success('Your credit card was added successfully!')
          }}
        />
      )}
    </Card>
  )
})
