import { zodResolver } from '@hookform/resolvers/zod'
import { Container, Divider, Paper } from '@tidbcloud/uikit'
import { observer } from 'mobx-react'
import { useEffect, useId } from 'react'
import { FormProvider, useForm } from 'react-hook-form'

import { queryClient } from 'dbaas/reactQueryClient'
import {
  invalidateCapacityLimitsQueries,
  PREMIUM_MAX_RCU_FALLBACK,
  PREMIUM_MIN_RCU,
  useCapacityLimits
} from 'dbaas/screens/NextGen/premium/capacity/shared/use-capacity-limits'
import { Capacity } from 'dbaas/screens/NextGen/premium/creation/shared/Capacity'
import { TidbDualLayerDataEncryption } from 'dbaas/screens/NextGen/premium/creation/shared/dual-layer-data-encryption/DualLayerDataEncription'
import { useDualLayerDataEncryptionFeatEnabled } from 'dbaas/screens/NextGen/premium/creation/shared/dual-layer-data-encryption/use-dual-layer-data-encryption-feat-enabled'
import { TidbCloudRegions } from 'dbaas/screens/NextGen/tidb-creation/shared/CloudRegions'
import { TidbHighAvailability } from 'dbaas/screens/NextGen/tidb-creation/shared/HighAvailability'
import { TidbDisplayName } from 'dbaas/screens/NextGen/tidb-creation/shared/TidbDisplayName'
import {
  useGetTidbCloudProviders,
  useGetTidbCloudRegions
} from 'dbaas/screens/NextGen/tidb-creation/shared/use-cloud-providers-regions'
import { useCreateTidb } from 'dbaas/screens/NextGen/tidb-creation/shared/use-create-tidb'
import {
  Commonv1beta1ServicePlan,
  V1beta1RegionCloudProvider,
  V1beta2TidbHighAvailabilityType
} from 'dbaas/services/api-clients/v2025/tidb-management/v1beta2/interface'
import { ExpFeatHashmap } from 'dbaas/stores/localStorage'
import useStores from 'dbaas/stores/useStores'

import { CreatePremiumActionsPanel } from './ActionsPanel'
import { createPremiumFormValueSchema } from './form-resolver'
import { CreatePremiumFormValue } from './types'

export const CreatePremiumForm = observer(() => {
  const {
    store: {
      lastVisitLocation: { orgId, projectId },
      expWhiteList
    }
  } = useStores()

  const isBYOC = expWhiteList[ExpFeatHashmap.BYOCEnable]
  const servicePlan = isBYOC ? Commonv1beta1ServicePlan.BYOC : Commonv1beta1ServicePlan.Premium

  const formId = useId()
  const formInstance = useForm<CreatePremiumFormValue>({
    mode: 'onChange',
    defaultValues: {
      servicePlan: servicePlan,
      cloudProvider: undefined,
      regionId: '',
      name: '',
      maxRcu: 20000,
      highAvailabilityType: V1beta2TidbHighAvailabilityType.REGIONAL,
      dualLayerDataEncryption: {
        encrypted: false,
        keyType: 'service-managed',
        awsCmek: {
          accountId: '',
          kmsKeyArn: ''
        },
        aliyunCmek: {
          accountId: '',
          kmsKeyArn: ''
        }
      }
    },
    resolver: zodResolver(createPremiumFormValueSchema(servicePlan, orgId, projectId))
  })

  const { watch, setValue, handleSubmit } = formInstance

  const createMutator = useCreateTidb()
  const onSubmit = handleSubmit((data) => {
    if (data.dualLayerDataEncryption.encrypted && data.dualLayerDataEncryption.keyType === 'customer-managed') {
      if (
        data.cloudProvider === V1beta1RegionCloudProvider.aws &&
        !data.dualLayerDataEncryption.awsCmek?.kmsKeyArn?.trim()
      ) {
        return
      }

      if (
        data.cloudProvider === V1beta1RegionCloudProvider.alicloud &&
        !data.dualLayerDataEncryption.aliyunCmek?.kmsKeyArn?.trim()
      ) {
        return
      }
    }

    return createMutator
      .mutateAsync({
        data: {
          servicePlan,
          displayName: data.name,
          cloudProvider: data.cloudProvider,
          regionId: data.regionId,
          maxRcu: String(data.maxRcu),
          highAvailabilityType: data.highAvailabilityType,
          dualLayerDataEncryption: data.dualLayerDataEncryption.encrypted
            ? {
                defaultKey: data.dualLayerDataEncryption.keyType === 'service-managed' ? {} : undefined,
                cmek:
                  data.dualLayerDataEncryption.keyType === 'customer-managed'
                    ? {
                        servicePlan,
                        regionId: data.regionId,
                        ...(data.cloudProvider === V1beta1RegionCloudProvider.aws
                          ? {
                              awsKms: {
                                kmsKeyArn: data.dualLayerDataEncryption.awsCmek?.kmsKeyArn?.trim()!
                              },
                              awsPrincipal: {
                                accountId: data.dualLayerDataEncryption.awsCmek?.accountId!
                              }
                            }
                          : {
                              aliyunKms: {
                                kmsKeyArn: data.dualLayerDataEncryption.aliyunCmek?.kmsKeyArn?.trim()!
                              },
                              aliyunPrincipal: {
                                accountId: data.dualLayerDataEncryption.aliyunCmek?.accountId!
                              }
                            })
                      }
                    : undefined
              }
            : undefined
        },
        params: {
          orgId,
          projectId
        }
      })
      .then((result) => {
        // Invalidate capacity limits queries to refresh quota data
        invalidateCapacityLimitsQueries(queryClient, servicePlan, orgId, projectId)
        return result
      })
  })

  const cloudProvider = watch('cloudProvider')
  const { cloudProviders, isLoading: isLoadingProviders } = useGetTidbCloudProviders(servicePlan)
  const { regions, isLoading: isLoadingRegions } = useGetTidbCloudRegions(servicePlan, cloudProvider)
  const regionId = watch('regionId')
  const isLoading = isLoadingProviders || isLoadingRegions

  // Check quota to disable submit button if insufficient
  const { instanceMaxRcu, availableTotalRcu } = useCapacityLimits({ servicePlan })
  const effectiveLimit = Math.min(
    instanceMaxRcu ?? PREMIUM_MAX_RCU_FALLBACK,
    availableTotalRcu ?? PREMIUM_MAX_RCU_FALLBACK
  )
  const isQuotaInsufficient = effectiveLimit < PREMIUM_MIN_RCU

  // Check if the dual layer data encryption feature is enabled
  const { isEnabled: isDataEncryptionFeatEnabled } = useDualLayerDataEncryptionFeatEnabled({
    servicePlan,
    cloudProvider
  })

  useEffect(() => {
    setValue('cloudProvider', cloudProviders?.[0] ?? '')
  }, [cloudProviders, setValue])

  useEffect(() => {
    setValue('regionId', regions?.[0]?.regionId ?? '')
  }, [regions, setValue])

  useEffect(() => {
    if (isBYOC) {
      setValue('servicePlan', Commonv1beta1ServicePlan.BYOC)
    }
  }, [isBYOC, setValue])

  return (
    <Container size={880} px={0}>
      <FormProvider {...formInstance}>
        <Paper component="form" id={formId} withBorder shadow="none" onSubmit={onSubmit}>
          <TidbDisplayName />
          <Divider />
          <TidbCloudRegions cloudProviders={cloudProviders} regions={regions} disabled={isLoading} />
          <Divider />
          <Capacity servicePlan={servicePlan} />
          <Divider />
          {isDataEncryptionFeatEnabled && (
            <>
              <TidbDualLayerDataEncryption
                servicePlan={servicePlan}
                cloudProvider={cloudProvider}
                regionId={regionId}
              />
              <Divider />
            </>
          )}
          <TidbHighAvailability
            extraDesc="Premium supports only regional high availability."
            optionsOverride={{
              ZONAL: {
                disabled: true
              }
            }}
          />
          <Divider />
          <CreatePremiumActionsPanel
            formId={formId}
            isLoading={isLoading}
            isPending={createMutator.isLoading}
            disabled={isQuotaInsufficient}
            servicePlan={servicePlan}
          />
        </Paper>
      </FormProvider>
    </Container>
  )
})
