import { ActionIcon, Alert, Box, Button, Group, Paper, Stack, Typography } from '@tidbcloud/uikit'
import { FormRadioGroup, FormSwitch } from '@tidbcloud/uikit/biz'
import { useDisclosure, usePrevious } from '@tidbcloud/uikit/hooks'
import { IconXClose } from '@tidbcloud/uikit/icons'
import { useEffect } from 'react'
import { FieldError, useFormContext } from 'react-hook-form'

import {
  Commonv1beta1ServicePlan,
  V1beta1RegionCloudProvider
} from 'dbaas/services/api-clients/v2025/tidb-management/v1beta2/interface'

import { AddAliyunKmsKeyModal } from './AddAliyunKmsKeyModal'
import { AddAwsKmsKeyArnModal } from './AddAwsKmsKeyArnModal'
import { CheckAliyunKeyPolicyModal } from './CheckAliyunKeyPolicyModal'
import { CheckAwsKeyPolicyModal } from './CheckAwsKeyPolicyModal'
import { useSyncAliyunCmekRamRole } from './use-sync-aliyun-cmek-ram-role'
import { useSyncAwsCmekAccountId } from './use-sync-aws-cmek-account-id'

interface DualLayerDataEncryptionFormValue {
  dualLayerDataEncryption: {
    encrypted: boolean
    keyType?: 'service-managed' | 'customer-managed'
    awsCmek?: {
      accountId: string | undefined
      kmsKeyArn: string | undefined
    }
    aliyunCmek?: {
      accountId: string | undefined
      kmsKeyArn: string | undefined
    }
  }
}

interface TidbDualLayerDataEncryptionProps {
  servicePlan: Commonv1beta1ServicePlan
  cloudProvider: V1beta1RegionCloudProvider
  regionId: string
  projectId: string
  readOnly?: boolean
  names?: {
    encrypted: string
    keyType: string
    awsKmsKeyArn: string
    awsAccountId: string
    aliyunKmsKeyArn: string
    aliyunAccountId: string
  }
}

export const TidbDualLayerDataEncryption = ({
  servicePlan,
  cloudProvider,
  regionId,
  projectId,
  readOnly = false,
  names = {
    encrypted: 'dualLayerDataEncryption.encrypted',
    keyType: 'dualLayerDataEncryption.keyType',
    awsKmsKeyArn: 'dualLayerDataEncryption.awsCmek.kmsKeyArn',
    awsAccountId: 'dualLayerDataEncryption.awsCmek.accountId',
    aliyunKmsKeyArn: 'dualLayerDataEncryption.aliyunCmek.kmsKeyArn',
    aliyunAccountId: 'dualLayerDataEncryption.aliyunCmek.accountId'
  }
}: TidbDualLayerDataEncryptionProps) => {
  const formItemNames = {
    encrypted: names.encrypted as 'dualLayerDataEncryption.encrypted',
    keyType: names.keyType as 'dualLayerDataEncryption.keyType',
    awsKmsKeyArn: names.awsKmsKeyArn as 'dualLayerDataEncryption.awsCmek.kmsKeyArn',
    awsAccountId: names.awsAccountId as 'dualLayerDataEncryption.awsCmek.accountId',
    aliyunKmsKeyArn: names.aliyunKmsKeyArn as 'dualLayerDataEncryption.aliyunCmek.kmsKeyArn',
    aliyunAccountId: names.aliyunAccountId as 'dualLayerDataEncryption.aliyunCmek.accountId'
  }
  const { watch, register, getValues, setValue, formState, getFieldState, clearErrors } =
    useFormContext<DualLayerDataEncryptionFormValue>()
  const encrypted = watch(formItemNames.encrypted)
  const keyType = watch(formItemNames.keyType)
  const isAws = cloudProvider === V1beta1RegionCloudProvider.aws
  const isAliyun = cloudProvider === V1beta1RegionCloudProvider.alicloud
  const awsKmsKeyArn = watch(formItemNames.awsKmsKeyArn)
  const aliyunKmsKeyArn = watch(formItemNames.aliyunKmsKeyArn)

  const prevCloudProvider = usePrevious(cloudProvider)
  const prevRegionId = usePrevious(regionId)

  const awsKmsKeyArnErrorState = getFieldState(formItemNames.awsKmsKeyArn, formState).error as FieldError | undefined
  const aliyunKmsKeyArnErrorState = getFieldState(formItemNames.aliyunKmsKeyArn, formState).error as
    | FieldError
    | undefined
  const currentError = isAws ? awsKmsKeyArnErrorState?.message : aliyunKmsKeyArnErrorState?.message

  useEffect(() => {
    if (!readOnly && (prevCloudProvider !== cloudProvider || prevRegionId !== regionId)) {
      if (keyType === 'customer-managed') {
        setValue(formItemNames.awsKmsKeyArn, '')
        setValue(formItemNames.awsAccountId, '')
        setValue(formItemNames.aliyunKmsKeyArn, '')
        setValue(formItemNames.aliyunAccountId, '')
      }
    }
  }, [
    cloudProvider,
    regionId,
    setValue,
    keyType,
    prevCloudProvider,
    prevRegionId,
    readOnly,
    formItemNames.awsKmsKeyArn,
    formItemNames.awsAccountId,
    formItemNames.aliyunKmsKeyArn,
    formItemNames.aliyunAccountId
  ])

  const awsCmekAccountIdSyncQuery = useSyncAwsCmekAccountId({
    enabled: isAws && keyType === 'customer-managed' && !!readOnly,
    servicePlan,
    regionId,
    projectId,
    onSuccess: (latestAccountId) => {
      const currentAccountId = getValues(formItemNames.awsAccountId)

      if (currentAccountId !== latestAccountId) {
        setValue(formItemNames.awsAccountId, latestAccountId)
      }
    }
  })
  const aliyunCmekRamRoleSyncQuery = useSyncAliyunCmekRamRole({
    enabled: isAliyun && keyType === 'customer-managed' && !!readOnly,
    servicePlan,
    regionId,
    projectId,
    onSuccess: (latestAccountId) => {
      const currentAccountId = getValues(formItemNames.aliyunAccountId)

      if (currentAccountId !== latestAccountId) {
        setValue(formItemNames.aliyunAccountId, latestAccountId)
      }
    }
  })

  const [addAwsKmsKeyArnModalOpened, addAwsKmsKeyArnModalHandlers] = useDisclosure()
  const [checkAwsKmsPolicyModalOpened, checkAwsKmsPolicyModalHandlers] = useDisclosure()
  const [addAliyunKmsKeyModalOpened, addAliyunKmsKeyModalHandlers] = useDisclosure()
  const [checkAliyunKmsPolicyModalOpened, checkAliyunKmsPolicyModalHandlers] = useDisclosure()
  const currentKeyConfigured = isAws ? !!awsKmsKeyArn : !!aliyunKmsKeyArn

  return (
    <Stack gap="xl" p="xl">
      <Group justify="space-between" align="flex-start" wrap="nowrap">
        <Box>
          <Typography variant="title-lg">Dual-Layer Data Encryption</Typography>
          <Typography variant="body-lg" c="carbon.7">
            Add a second layer of encryption on top of the encryption at rest with an isolated service-managed key or a
            customer-managed encryption key (CMEK).
          </Typography>
        </Box>
        <FormSwitch name={names.encrypted} disabled={readOnly} />
      </Group>
      {encrypted && (
        <>
          <FormRadioGroup
            name={names.keyType}
            data={[
              { label: 'Service-managed Encryption Key', value: 'service-managed', disabled: readOnly },
              { label: 'Customer-managed Encryption Key (CMEK)', value: 'customer-managed', disabled: readOnly }
            ]}
            sx={{
              '& > [role="radiogroup"] > .mantine-Flex-root': {
                marginTop: '0 !important'
              }
            }}
          />
          <input type="hidden" {...register(formItemNames.awsKmsKeyArn)} />
          <input type="hidden" {...register(formItemNames.awsAccountId)} />
          <input type="hidden" {...register(formItemNames.aliyunKmsKeyArn)} />
          <input type="hidden" {...register(formItemNames.aliyunAccountId)} />
          {keyType === 'customer-managed' && currentKeyConfigured && (
            <Paper bg="carbon.2" p="sm">
              <Group justify="space-between">
                <Group wrap="nowrap">
                  <Typography variant="label-lg" c="carbon.7">
                    KMS Key ARN
                  </Typography>
                  <Typography variant="body-lg">{isAws ? awsKmsKeyArn : aliyunKmsKeyArn}</Typography>
                </Group>
                {!readOnly && (
                  <ActionIcon
                    variant="transparent"
                    size="sm"
                    onClick={() => {
                      if (isAws) {
                        setValue(formItemNames.awsKmsKeyArn, '')
                        setValue(formItemNames.awsAccountId, '')
                      }

                      if (isAliyun) {
                        setValue(formItemNames.aliyunKmsKeyArn, '')
                        setValue(formItemNames.aliyunAccountId, '')
                      }
                    }}
                    c="carbon.7"
                  >
                    <IconXClose />
                  </ActionIcon>
                )}
              </Group>
            </Paper>
          )}
          {readOnly && keyType === 'customer-managed' && (
            <Alert py={8}>
              <Group justify="space-between">
                <Typography variant="body-lg">
                  {isAws
                    ? 'The key ARN is fixed and must match the source instance. Make sure the key policy grants access to the TiDB Cloud account ID used by the new instance.'
                    : 'The key configuration is fixed and must match the source instance. Make sure the key policy grants access to the TiDB Cloud account ID used by the new instance.'}
                </Typography>
                <Button
                  variant="default"
                  size="sm"
                  disabled={isAws ? awsCmekAccountIdSyncQuery.isLoading : aliyunCmekRamRoleSyncQuery.isLoading}
                  onClick={() => {
                    if (isAws) {
                      checkAwsKmsPolicyModalHandlers.open()
                    }

                    if (isAliyun) {
                      checkAliyunKmsPolicyModalHandlers.open()
                    }
                  }}
                >
                  Check Key Policy
                </Button>
              </Group>
            </Alert>
          )}
          {!readOnly && keyType === 'customer-managed' && !currentKeyConfigured && (
            <>
              {currentError && (
                <Alert color="red" py={8}>
                  <Group justify="space-between">
                    <Typography variant="body-lg">{currentError}</Typography>
                    <Button
                      variant="default"
                      size="sm"
                      onClick={() => {
                        if (isAws) {
                          clearErrors(formItemNames.awsKmsKeyArn)
                          addAwsKmsKeyArnModalHandlers.open()
                        }

                        if (isAliyun) {
                          clearErrors(formItemNames.aliyunKmsKeyArn)
                          addAliyunKmsKeyModalHandlers.open()
                        }
                      }}
                    >
                      {isAws ? 'Add KMS Key ARN' : 'Add KMS Key'}
                    </Button>
                  </Group>
                </Alert>
              )}
              {!currentError && (
                <Button
                  variant="default"
                  size="sm"
                  onClick={() => {
                    if (isAws) {
                      addAwsKmsKeyArnModalHandlers.open()
                    }

                    if (isAliyun) {
                      addAliyunKmsKeyModalHandlers.open()
                    }
                  }}
                  sx={{ alignSelf: 'flex-start' }}
                >
                  {isAws ? 'Add KMS Key ARN' : 'Add KMS Key'}
                </Button>
              )}
            </>
          )}
          {!readOnly && keyType === 'customer-managed' && isAws && (
            <AddAwsKmsKeyArnModal
              servicePlan={servicePlan}
              regionId={regionId}
              projectId={projectId}
              opened={addAwsKmsKeyArnModalOpened}
              onClose={addAwsKmsKeyArnModalHandlers.close}
              onFinish={(data) => {
                setValue(formItemNames.awsKmsKeyArn, data.kmsKeyArn)
                setValue(formItemNames.awsAccountId, data.accountId)
                addAwsKmsKeyArnModalHandlers.close()
              }}
            />
          )}
          {!readOnly && keyType === 'customer-managed' && isAliyun && (
            <AddAliyunKmsKeyModal
              servicePlan={servicePlan}
              regionId={regionId}
              projectId={projectId}
              opened={addAliyunKmsKeyModalOpened}
              onClose={addAliyunKmsKeyModalHandlers.close}
              onFinish={(data) => {
                setValue(formItemNames.aliyunKmsKeyArn, data.kmsKeyArn)
                setValue(formItemNames.aliyunAccountId, data.accountId)
                addAliyunKmsKeyModalHandlers.close()
              }}
            />
          )}
          {readOnly && keyType === 'customer-managed' && isAws && (
            <CheckAwsKeyPolicyModal
              accountId={awsCmekAccountIdSyncQuery.accountId}
              externalId={awsCmekAccountIdSyncQuery.externalId}
              regionId={regionId}
              kmsKeyArn={awsKmsKeyArn ?? ''}
              opened={checkAwsKmsPolicyModalOpened}
              onClose={checkAwsKmsPolicyModalHandlers.close}
            />
          )}
          {readOnly && keyType === 'customer-managed' && isAliyun && (
            <CheckAliyunKeyPolicyModal
              accountId={aliyunCmekRamRoleSyncQuery.accountId}
              kmsKeyArn={aliyunKmsKeyArn ?? ''}
              opened={checkAliyunKmsPolicyModalOpened}
              onClose={checkAliyunKmsPolicyModalHandlers.close}
            />
          )}
        </>
      )}
    </Stack>
  )
}
