import {
  ActionIcon,
  Alert,
  Anchor,
  Button,
  Card,
  Divider,
  Drawer,
  Group,
  HoverCard,
  Input,
  Loader,
  Menu,
  Modal,
  notifier,
  Pill,
  Stack,
  Typography,
  Box
} from '@tidbcloud/uikit'
import {
  FormErrorMessage,
  FormSelect,
  FormTextInput,
  MRT_ColumnDef,
  PropertyCard,
  ProTable
} from '@tidbcloud/uikit/biz'
import { useDisclosure } from '@tidbcloud/uikit/hooks'
import { IconAlertCircle, IconDotsHorizontal, IconInfoCircle } from '@tidbcloud/uikit/icons'
import { useMemo, useState } from 'react'
import { FormProvider, useForm } from 'react-hook-form'
import { useQuery } from 'react-query'

import { StatusBadge, StatusVariantMap } from 'dbaas/components/StatusBadge'
import TimeComponent from 'dbaas/components/TimeComponent'
import { AccessGuard, DEFAULT_HINT_CONTENT, useAccessCheck } from 'dbaas/contexts/access-control'
import { CloudProvidersDescription } from 'dbaas/features/Billing/provider'
import { SharedCluster } from 'dbaas/features/ClusterManagement/cluster'
import { useOrgProjectClusterIds } from 'dbaas/features/Common'
import { CloudProviderConst } from 'dbaas/features/Project'
import {
  useClusterServiceCheckFeature,
  usePrivateLinkConnectionServiceAttachDomains,
  usePrivateLinkConnectionServiceCreatePrivateLinkConnection,
  usePrivateLinkConnectionServiceDeletePrivateLinkConnection,
  usePrivateLinkConnectionServiceDetachDomains,
  usePrivateLinkConnectionServiceGetAvailabilityZones,
  usePrivateLinkConnectionServiceListPrivateLinkConnections
} from 'dbaas/services/api-clients/legacy/serverless'
import {
  PrivateLinkConnectionDomainTypeEnum,
  PrivateLinkConnectionStateEnum,
  PrivateLinkConnectionTypeEnum,
  type PrivateLinkConnection
} from 'dbaas/services/api-clients/legacy/serverless/interface'
import { getErrorMessage } from 'dbaas/services/errorCodes'

const PRIVATE_LINK_TYPE_LABELS: Record<PrivateLinkConnectionTypeEnum, string> = {
  [PrivateLinkConnectionTypeEnum.AWS_ENDPOINT_SERVICE]: 'AWS Endpoint Service',
  [PrivateLinkConnectionTypeEnum.ALICLOUD_ENDPOINT_SERVICE]: 'Alibaba Cloud Endpoint Service',
  [PrivateLinkConnectionTypeEnum.AMAZON_MSK_PROVISIONED]: 'Amazon MSK Provisioned'
}

const getPrivateLinkTypeLabel = (type?: PrivateLinkConnection['type']) =>
  (type && PRIVATE_LINK_TYPE_LABELS[type as PrivateLinkConnectionTypeEnum]) || type || '-'

type StatusBadgeVariant = 'default' | 'success' | 'danger' | 'warning' | 'primary'

const PRIVATE_LINK_STATUS_MAP: Record<
  PrivateLinkConnectionStateEnum,
  { label: string; color: 'green' | 'red' | 'yellow' | 'blue' }
> = {
  [PrivateLinkConnectionStateEnum.ACTIVE]: { label: 'Active', color: 'green' },
  [PrivateLinkConnectionStateEnum.CREATING]: { label: 'Creating', color: 'blue' },
  [PrivateLinkConnectionStateEnum.PENDING_ACCEPTANCE]: { label: 'Pending acceptance', color: 'yellow' },
  [PrivateLinkConnectionStateEnum.DELETING]: { label: 'Deleting', color: 'yellow' },
  [PrivateLinkConnectionStateEnum.FAILED]: { label: 'Failed', color: 'red' }
}

const getPrivateLinkStatus = (status?: PrivateLinkConnection['state']) => {
  if (!status) {
    return { label: '-', color: undefined, variant: 'default' as StatusBadgeVariant }
  }
  const mapped = PRIVATE_LINK_STATUS_MAP[status as PrivateLinkConnectionStateEnum]
  if (!mapped) {
    return { label: status, color: undefined, variant: 'default' as StatusBadgeVariant }
  }
  return {
    label: mapped.label,
    color: mapped.color,
    variant: (StatusVariantMap[mapped.color] ?? 'default') as StatusBadgeVariant
  }
}

const PENDING_ACCEPTANCE_TIPS: Record<PrivateLinkConnectionTypeEnum, string> = {
  [PrivateLinkConnectionTypeEnum.AWS_ENDPOINT_SERVICE]:
    'Please go to the detail page of your endpoint service on the AWS console. In the Endpoint Connections tab, accept the endpoint connection request from TiDB Cloud.',
  [PrivateLinkConnectionTypeEnum.ALICLOUD_ENDPOINT_SERVICE]:
    'Please go to the detail page of your endpoint service on the Alibaba Cloud console. In the Endpoint Connections tab, allow the endpoint connection request from TiDB Cloud.',
  [PrivateLinkConnectionTypeEnum.AMAZON_MSK_PROVISIONED]:
    'Please go to AWS console and verify the corresponding Amazon MSK VPC Connection status is accepted and available.'
}

const PrivateLinkStatus = ({
  state,
  type,
  showPendingTip = true
}: {
  state?: PrivateLinkConnection['state']
  type?: PrivateLinkConnection['type']
  showPendingTip?: boolean
}) => {
  const status = getPrivateLinkStatus(state)
  const pendingTip =
    showPendingTip && state === PrivateLinkConnectionStateEnum.PENDING_ACCEPTANCE
      ? PENDING_ACCEPTANCE_TIPS[type as PrivateLinkConnectionTypeEnum]
      : ''
  return (
    <Group gap={8} wrap="nowrap">
      <StatusBadge status={status.label} color={status.color} variant={status.variant} />
      {pendingTip && (
        <HoverCard>
          <HoverCard.Target>
            <IconInfoCircle size={14} />
          </HoverCard.Target>
          <HoverCard.Dropdown maw={500}>{pendingTip}</HoverCard.Dropdown>
        </HoverCard>
      )}
    </Group>
  )
}

export function EssentialPrivateLink({ cluster }: { cluster: SharedCluster }) {
  const { orgId, projectId } = useOrgProjectClusterIds()
  const providerName = CloudProvidersDescription[cluster.provider.toUpperCase()]
  const privateEndpointTitle = [providerName, 'Private Endpoints for External Services'].filter(Boolean).join(' ')
  const privateEndpointDescription =
    cluster.provider === CloudProviderConst.AWS
      ? 'Create a Private Endpoint to securely connect Data Migration or Changefeed to an external database. Powered by AWS PrivateLink, traffic stays within the AWS network without traversing the public internet. A Private Endpoint can be reused on this instance.'
      : 'Create a Private Endpoint to securely connect Data Migration or Changefeed to an external database. Powered by cloud provider private connectivity, traffic stays within the cloud provider network without traversing the public internet. A Private Endpoint can be reused on this instance.'
  const [pagination, setPagination] = useState({ pageIndex: 0, pageSize: 5 })
  const {
    data: isFeatureSupported,
    isLoading: isLoadingCheckFeature,
    error: checkFeatureError
  } = useClusterServiceCheckFeature(
    orgId,
    projectId,
    cluster.id,
    {
      feature_name: 'PRIVATE_LINK_CONNECTION'
    },
    {
      query: {
        refetchOnMount: false,
        refetchOnWindowFocus: false,
        retry: false,
        select(data) {
          return data.success
        }
      }
    }
  )
  const supported = Boolean(isFeatureSupported) && !checkFeatureError

  const { data, isLoading, refetch } = usePrivateLinkConnectionServiceListPrivateLinkConnections(
    orgId,
    projectId,
    cluster.id,
    {
      page_size: pagination.pageSize,
      page_token: (pagination.pageIndex + 1).toString()
    },
    {
      query: {
        enabled: cluster.computed.isEssential && !!orgId && !!projectId && !!cluster.id && supported,
        refetchOnWindowFocus: false,
        refetchInterval: 30_000
      }
    }
  )
  const privateLinkConnections = data?.private_link_connections ?? []
  const [current, setCurrent] = useState<PrivateLinkConnection | null>(null)
  const [createModalOpened, createModalHandler] = useDisclosure()
  const [viewModalOpened, viewModalHandler] = useDisclosure()
  const [deleteModalOpened, deleteModalHandler] = useDisclosure()
  const [attachDomainModalOpened, attachDomainModalHandler] = useDisclosure()
  const [detachDomainModalOpened, detachDomainModalHandler] = useDisclosure()
  const handleViewDetail = (row: PrivateLinkConnection) => {
    setCurrent(row)
    viewModalHandler.open()
  }
  const handleDelete = (row: PrivateLinkConnection) => {
    setCurrent(row)
    deleteModalHandler.open()
  }
  const handleDeleteConfirm = async () => {
    if (current) {
      await deletePrivateLinkConnection.mutateAsync({
        orgId,
        projectId,
        clusterId: cluster.id,
        privateLinkConnectionId: current.private_link_connection_id!
      })
      notifier.success('Private link connection has been deleted.')
      deleteModalHandler.close()
    }
  }
  const handleAttachDomain = (row: PrivateLinkConnection) => {
    setCurrent(row)
    attachDomainModalHandler.open()
  }
  const handleDetachDomain = (row: PrivateLinkConnection) => {
    setCurrent(row)
    detachDomainModalHandler.open()
  }
  const deletePrivateLinkConnection = usePrivateLinkConnectionServiceDeletePrivateLinkConnection({
    mutation: {
      onSuccess: () => refetch()
    }
  })
  const columns: MRT_ColumnDef<PrivateLinkConnection>[] = [
    {
      header: 'name',
      Header: () => {
        return <Typography pl={16}>Name</Typography>
      },
      accessorFn(originalRow) {
        return (
          <Anchor ml={16} onClick={() => handleViewDetail(originalRow)}>
            {originalRow.display_name}
          </Anchor>
        )
      }
    },
    {
      header: 'Status',
      accessorFn(originalRow) {
        return <PrivateLinkStatus state={originalRow.state} type={originalRow.type} />
      }
    },
    {
      header: 'Type',
      accessorFn(originalRow) {
        return <Typography>{getPrivateLinkTypeLabel(originalRow.type)}</Typography>
      }
    },
    {
      header: 'Creation Time',
      accessorFn(originalRow) {
        return <TimeComponent time={originalRow.create_time!} />
      }
    },
    {
      id: 'actions',
      header: '',
      size: 80,
      accessorFn(originalRow) {
        return (
          <Menu>
            <Menu.Target>
              <ActionIcon data-testid="networking-private-link-row-actions">
                <IconDotsHorizontal size={16} />
              </ActionIcon>
            </Menu.Target>

            <Menu.Dropdown>
              <Menu.Item onClick={() => handleViewDetail(originalRow)}>View</Menu.Item>
              {!!originalRow.attached_domains?.length ? (
                <Menu.Item
                  disabled={!actionAccessible}
                  onClick={() => handleDetachDomain(originalRow)}
                  data-testid="networking-private-link-detach-domain"
                >
                  Detach Domain
                </Menu.Item>
              ) : originalRow.type !== 'AMAZON_MSK_PROVISIONED' ? (
                <Menu.Item
                  disabled={!actionAccessible}
                  onClick={() => handleAttachDomain(originalRow)}
                  data-testid="networking-private-link-attach-domain"
                >
                  Attach Domain
                </Menu.Item>
              ) : null}
              <Menu.Item
                disabled={!actionAccessible}
                onClick={() => handleDelete(originalRow)}
                data-testid="networking-private-link-delete"
              >
                Delete
              </Menu.Item>
            </Menu.Dropdown>
          </Menu>
        )
      }
    }
  ]

  const actionAccessible = useAccessCheck('TidbxNetworkingUpdate', { tidbId: cluster.id })

  return (
    <Card p="xl">
      <Stack>
        <Group justify="space-between" wrap="nowrap" align="flex-start">
          <Stack gap={8} sx={{ flex: 1 }}>
            <Group gap={8}>
              <Typography variant="title-lg">{privateEndpointTitle}</Typography>
              {(isLoading || isLoadingCheckFeature) && <Loader size="xs" />}
            </Group>
            <Typography variant="body-md" c="carbon.7" maw={760}>
              {privateEndpointDescription}{' '}
              <a
                href="https://docs.pingcap.com/tidbcloud/serverless-private-link-connection/?plan=essential"
                target="_blank"
                rel="noreferrer"
              >
                Learn more
              </a>
              .
            </Typography>
          </Stack>
          <HoverCard disabled={supported && actionAccessible}>
            <HoverCard.Target>
              <Box>
                <Button
                  variant="default"
                  size="sm"
                  onClick={createModalHandler.open}
                  data-testid="networking-private-link-create"
                  disabled={!actionAccessible || !supported}
                >
                  Create Private Endpoint for External Services
                </Button>
              </Box>
            </HoverCard.Target>
            <HoverCard.Dropdown maw={500}>
              {!supported &&
                `Private Link is currently unavailable in the ${cluster.region} region. Please contact support for assistance.`}
              {!actionAccessible && DEFAULT_HINT_CONTENT}
            </HoverCard.Dropdown>
          </HoverCard>
        </Group>

        {(isLoading || privateLinkConnections.length > 0) && (
          <ProTable
            columns={columns}
            data={privateLinkConnections}
            loading={isLoading}
            enablePagination
            state={{ pagination }}
            rowCount={data?.total_size || 0}
            onPaginationChange={setPagination}
            pagination={{
              showRowsPerPage: true,
              showTotal: true
            }}
          />
        )}
      </Stack>

      <Drawer
        title={
          <Typography variant="title-lg" px={8}>
            Private Link Connection Detail
          </Typography>
        }
        size="lg"
        opened={viewModalOpened}
        onClose={viewModalHandler.close}
        position="right"
      >
        {current && <PrivateLinkConnectionDetail data={current!} />}
      </Drawer>

      <AccessGuard id="TidbxNetworkingUpdate" scopeProps={{ tidbId: cluster.id }}>
        <Modal
          title="Create Private Endpoint for External Services"
          opened={createModalOpened}
          onClose={createModalHandler.close}
          size="lg"
        >
          <CreatePrivateLinkConnection cluster={cluster} onClose={createModalHandler.close} onCreated={refetch} />
        </Modal>

        <Modal title="Confirm to delete" size="lg" opened={deleteModalOpened} onClose={deleteModalHandler.close}>
          <Stack>
            <Typography>
              Are you sure you want to delete the private link connection <b>{current?.display_name}</b>? This action
              cannot be undone.
            </Typography>

            <FormErrorMessage message={getErrorMessage(deletePrivateLinkConnection.error, true)} />

            <Group justify="flex-end">
              <Button variant="default" onClick={deleteModalHandler.close}>
                Cancel
              </Button>
              <Button
                color="red"
                variant="light"
                loading={deletePrivateLinkConnection.isLoading}
                onClick={handleDeleteConfirm}
              >
                I understand, continue
              </Button>
            </Group>
          </Stack>
        </Modal>

        <Modal
          title="Attach Domains"
          size="lg"
          opened={attachDomainModalOpened}
          onClose={attachDomainModalHandler.close}
        >
          {current && (
            <AttachDomains
              cluster={cluster}
              privateLink={current!}
              onClose={() => {
                attachDomainModalHandler.close()
                refetch()
              }}
            />
          )}
        </Modal>

        <Modal
          title="Confirm to detach domain"
          size="lg"
          opened={detachDomainModalOpened}
          onClose={detachDomainModalHandler.close}
        >
          <DetachDomain
            privateLink={current!}
            onClose={() => {
              detachDomainModalHandler.close()
              refetch()
            }}
          />
        </Modal>
      </AccessGuard>
    </Card>
  )
}

function PrivateLinkConnectionDetail({ data }: { data: PrivateLinkConnection }) {
  const columns: MRT_ColumnDef<{ domain: string; status: string; create_time: string }>[] = [
    {
      header: 'Domain',
      Header: () => {
        return <Typography pl={16}>Name</Typography>
      },
      accessorFn(originalRow) {
        return (
          <Typography ml={16} sx={{ whiteSpace: 'nowrap' }}>
            {originalRow.domain}
          </Typography>
        )
      }
    },
    {
      header: 'Status',
      maxSize: 80,
      accessorFn(originalRow) {
        return <Typography>{originalRow.status}</Typography>
      }
    },
    {
      header: 'Creation Time',
      accessorFn(originalRow) {
        return <TimeComponent time={originalRow.create_time} />
      }
    }
  ]
  const damainsData =
    data.attached_domains?.at(0)?.domains?.map((domain) => ({
      domain: domain.name || '',
      status: domain.state || '',
      create_time: data.attached_domains?.at(0)?.create_time || ''
    })) ?? []
  const availabilityZones =
    data.aws_endpoint_service?.availability_zone_ids ||
    data.alicloud_endpoint_service?.availability_zone_ids ||
    data.amazon_msk_provisioned?.availability_zone_ids ||
    []
  const endpointName =
    data.aws_endpoint_service?.name || data.alicloud_endpoint_service?.name || data.amazon_msk_provisioned?.msk_arn
  const endpointId =
    data.aws_endpoint_service?.endpoint_id ||
    data.alicloud_endpoint_service?.endpoint_id ||
    data.amazon_msk_provisioned?.msk_vpc_connection_arn
  const isAmazonMSK = data.type === PrivateLinkConnectionTypeEnum.AMAZON_MSK_PROVISIONED

  return (
    <Stack p={8}>
      <PropertyCard withBorder={false} p={0} labelProps={{ miw: 160 }}>
        <PropertyCard.Item label="Name">{data.display_name}</PropertyCard.Item>
        <PropertyCard.Item label="ID">{data.private_link_connection_id}</PropertyCard.Item>
        <PropertyCard.Item label="Status">
          <PrivateLinkStatus state={data.state} type={data.type} />
        </PropertyCard.Item>
        <PropertyCard.Item label="Type">{getPrivateLinkTypeLabel(data.type)}</PropertyCard.Item>
        <PropertyCard.Item label={isAmazonMSK ? 'MSK Arn' : 'Endpoint Service Name'}>
          {endpointName || '-'}
        </PropertyCard.Item>
        <PropertyCard.Item label={isAmazonMSK ? 'MSK VPC Connection Arn' : 'Endpoint ID'}>
          {endpointId || '-'}
        </PropertyCard.Item>
        <PropertyCard.Item label="Availability Zones">
          {availabilityZones.length ? (
            <Pill.Group>
              {availabilityZones.map((zone) => (
                <Pill size="sm" key={zone}>
                  {zone}
                </Pill>
              ))}
            </Pill.Group>
          ) : (
            '-'
          )}
        </PropertyCard.Item>
        <PropertyCard.Item label="Creation Time">
          <TimeComponent time={data.create_time!} />
        </PropertyCard.Item>
        <PropertyCard.Item label="Created By">{data.created_by}</PropertyCard.Item>
      </PropertyCard>

      <Divider />

      <Typography variant="title-md" c="carbon.7" fw={500}>
        Attached Domains
      </Typography>

      {damainsData.length > 0 && <ProTable columns={columns} data={damainsData} emptyMessage="No attached domains" />}
    </Stack>
  )
}

interface CreateFormData {
  name: PrivateLinkConnection['display_name']
  type: PrivateLinkConnection['type']
  endpointServiceName: string
  mskVpcConnectionArn: string
}

function CreatePrivateLinkConnection({
  cluster,
  onClose,
  onCreated
}: {
  cluster: SharedCluster
  onClose: () => void
  onCreated: () => void
}) {
  const methods = useForm<CreateFormData>({
    defaultValues: {
      type:
        cluster.provider === CloudProviderConst.AWS
          ? PrivateLinkConnectionTypeEnum.AWS_ENDPOINT_SERVICE
          : PrivateLinkConnectionTypeEnum.ALICLOUD_ENDPOINT_SERVICE,
      name: '',
      endpointServiceName: '',
      mskVpcConnectionArn: ''
    }
  })
  const type = methods.watch('type')
  const connectionTypeOptions = [
    {
      label: 'AWS Endpoint Service',
      value: PrivateLinkConnectionTypeEnum.AWS_ENDPOINT_SERVICE,
      show: cluster.provider === CloudProviderConst.AWS
    },
    {
      label: 'Alibaba Cloud Endpoint Service',
      value: PrivateLinkConnectionTypeEnum.ALICLOUD_ENDPOINT_SERVICE,
      show: cluster.provider === CloudProviderConst.ALICLOUD
    },
    {
      label: 'Amazon MSK Provisioned',
      value: PrivateLinkConnectionTypeEnum.AMAZON_MSK_PROVISIONED,
      show: cluster.provider === CloudProviderConst.AWS
    }
  ]
    .filter((i) => i.show)
    .map(({ show, ...rest }) => rest)

  const { orgId, projectId } = useOrgProjectClusterIds()
  const clusterId = cluster.id
  const create = usePrivateLinkConnectionServiceCreatePrivateLinkConnection({
    mutation: {
      onSuccess: () => onCreated()
    }
  })
  const {
    data: availabilityZonesData,
    isLoading: availabilityZonesLoading,
    error: availabilityZonesError
  } = usePrivateLinkConnectionServiceGetAvailabilityZones(orgId, projectId, clusterId, {
    query: {
      enabled: !!orgId && !!projectId && !!clusterId,
      refetchOnWindowFocus: false,
      refetchOnMount: false
    }
  })
  const alertInfo = useMemo(() => {
    if (availabilityZonesLoading) {
      return 'Loading availability zones...'
    }
    if (availabilityZonesError) {
      return (
        <span>
          Failed to load availability zones.{' '}
          <span dangerouslySetInnerHTML={{ __html: getErrorMessage(availabilityZonesError, true) }}></span>
        </span>
      )
    }

    if (type === PrivateLinkConnectionTypeEnum.AWS_ENDPOINT_SERVICE) {
      return (
        <span>
          Please make sure the endpoint service allows the{' '}
          <b>{`arn:aws:iam::${availabilityZonesData?.account_id}:root`}</b> principal and has at least one of the
          following AZs: {availabilityZonesData?.az_ids?.join(', ')}.
        </span>
      )
    }
    if (type === PrivateLinkConnectionTypeEnum.ALICLOUD_ENDPOINT_SERVICE) {
      return (
        <span>
          Please make sure the endpoint service add <b>{`acs:ram:*:${availabilityZonesData?.account_id}:*`}</b> to the
          whitelist and has at least one of the following AZs: {availabilityZonesData?.az_ids?.join(', ')}.
        </span>
      )
    }
    if (type === PrivateLinkConnectionTypeEnum.AMAZON_MSK_PROVISIONED) {
      return (
        <span>
          Please make sure the Amazon MSK is attached with a cluster policy for account{' '}
          <b>{availabilityZonesData?.account_id}</b> and deployed in the same AZs as listed below:{' '}
          {availabilityZonesData?.az_ids?.join(', ')}.
        </span>
      )
    }
    return ''
  }, [type, availabilityZonesData, availabilityZonesLoading, availabilityZonesError])

  const handleSubmit = async (data: CreateFormData) => {
    try {
      await create.mutateAsync({
        orgId,
        projectId,
        clusterId,
        data: {
          private_link_connection: {
            cluster_id: clusterId,
            display_name: data.name,
            type: data.type,
            ...(data.type === PrivateLinkConnectionTypeEnum.AWS_ENDPOINT_SERVICE
              ? { aws_endpoint_service: { name: data.endpointServiceName } }
              : {}),
            ...(data.type === PrivateLinkConnectionTypeEnum.ALICLOUD_ENDPOINT_SERVICE
              ? { alicloud_endpoint_service: { name: data.endpointServiceName } }
              : {}),
            ...(data.type === PrivateLinkConnectionTypeEnum.AMAZON_MSK_PROVISIONED
              ? { amazon_msk_provisioned: { msk_arn: data.mskVpcConnectionArn } }
              : {})
          }
        }
      })

      notifier.success('Private link connection has been created.')
      onClose()
    } catch {}
  }

  return (
    <FormProvider {...methods}>
      <Stack component="form" onSubmit={methods.handleSubmit(handleSubmit)}>
        <FormTextInput
          name="name"
          label="Private Link Connection Name"
          placeholder="Enter your private link connection name"
          rules={{ required: 'Required' }}
        />

        <FormSelect
          name="type"
          label="Connection Type"
          data={connectionTypeOptions}
          placeholder="Select connection type"
        />

        {(type === PrivateLinkConnectionTypeEnum.AWS_ENDPOINT_SERVICE ||
          type === PrivateLinkConnectionTypeEnum.ALICLOUD_ENDPOINT_SERVICE) && (
          <FormTextInput
            name="endpointServiceName"
            label="Endpoint Service Name"
            placeholder="Enter your endpoint service name"
            rules={{ required: 'Required' }}
          />
        )}

        {type === PrivateLinkConnectionTypeEnum.AMAZON_MSK_PROVISIONED && (
          <FormTextInput
            name="mskVpcConnectionArn"
            label="MSK Cluster ARN"
            placeholder="Enter your MSK Cluster ARN"
            rules={{ required: 'Required' }}
          />
        )}

        {alertInfo && <Alert icon={<IconAlertCircle />}>{alertInfo}</Alert>}

        <Divider mx={-24} />

        <FormErrorMessage message={getErrorMessage(create.error, true)} />

        <Group justify="flex-end">
          <Button type="button" variant="default" onClick={onClose}>
            Cancel
          </Button>
          <Button type="submit" loading={create.isLoading}>
            Create
          </Button>
        </Group>
      </Stack>
    </FormProvider>
  )
}

interface AttachDomainsFormData {
  domainType: PrivateLinkConnectionDomainTypeEnum
  confluentId?: string
}

function AttachDomains({
  cluster,
  privateLink,
  onClose
}: {
  cluster: SharedCluster
  privateLink: PrivateLinkConnection
  onClose: () => void
}) {
  const methods = useForm<AttachDomainsFormData>({
    defaultValues: {
      domainType: 'TIDBCLOUD_MANAGED'
    }
  })
  const { orgId, projectId } = useOrgProjectClusterIds()
  const type = methods.watch('domainType')
  const uniqueName = methods.watch('confluentId')
  const attachDomain = usePrivateLinkConnectionServiceAttachDomains()

  const {
    data: generatedDomainData,
    isFetching: isLoadingGeneratedDomainData,
    refetch
  } = useQuery({
    queryKey: ['generateDomain', type, uniqueName],
    queryFn: async () => {
      return await attachDomain.mutateAsync({
        orgId,
        projectId,
        clusterId: cluster.id,
        privateLinkConnectionId: privateLink.private_link_connection_id!,
        data: {
          validate_only: true,
          attach_domain: {
            type,
            unique_name: type === 'CONFLUENT' ? uniqueName : undefined
          }
        }
      })
    },
    enabled: type === 'TIDBCLOUD_MANAGED',
    refetchOnWindowFocus: false,
    retry: false
  })

  const onSubmit = async (data: AttachDomainsFormData) => {
    await attachDomain.mutateAsync({
      orgId,
      projectId,
      clusterId: cluster.id,
      privateLinkConnectionId: privateLink.private_link_connection_id!,
      data: {
        validate_only: false,
        attach_domain: {
          type: data.domainType,
          unique_name: data.domainType === 'CONFLUENT' ? data.confluentId : generatedDomainData?.unique_name
        }
      }
    })

    notifier.success('Domain attach request submitted successfully.')
    onClose()
  }

  return (
    <FormProvider {...methods}>
      <Stack component="form" onSubmit={methods.handleSubmit(onSubmit)} gap="xl">
        <FormSelect
          name="domainType"
          label="Domain Type"
          data={[
            { label: 'TiDB Cloud Managed', value: PrivateLinkConnectionDomainTypeEnum.TIDBCLOUD_MANAGED },
            { label: 'Confluent', value: PrivateLinkConnectionDomainTypeEnum.CONFLUENT }
          ]}
        />

        {type === 'CONFLUENT' && (
          <Group>
            <FormTextInput
              name="confluentId"
              label={
                <Group gap={8}>
                  <Input.Label mb={0}>Confluent ID</Input.Label>
                  <HoverCard>
                    <HoverCard.Target>
                      <IconInfoCircle size={16} />
                    </HoverCard.Target>
                    <HoverCard.Dropdown maw={500}>
                      A Confluent ID uses the format {'<confluent_id>.<region>'}. For example, if the DNS subdomain of
                      your Confluent Cloud network of privatelink type is
                      use1-az1.domnprzqrog.us-east-1.aws.confluent.cloud, the corresponding Confluent ID would be
                      domnprzqrog.us-east-1. For more details, refer to the{' '}
                      <a
                        href="https://docs.pingcap.com/tidbcloud/serverless-private-link-connection-to-aws-confluent/?plan=essential"
                        target="_blank"
                        rel="noreferrer"
                      >
                        documentation
                      </a>
                      .
                    </HoverCard.Dropdown>
                  </HoverCard>
                </Group>
              }
              placeholder="Enter your unique confluent id to generate domain"
              rules={{ required: 'Required' }}
              sx={{ flex: 1 }}
            />

            <Button variant="default" mt={26} onClick={() => refetch()} loading={attachDomain.isLoading}>
              Generate
            </Button>
          </Group>
        )}

        {type === 'TIDBCLOUD_MANAGED' && isLoadingGeneratedDomainData && (
          <Group justify="center" align="center" gap={8}>
            <Loader size="xs" />
            <Typography variant="body-lg" c="carbon.7">
              Generating domain...
            </Typography>
          </Group>
        )}

        {generatedDomainData && !isLoadingGeneratedDomainData && (
          <Stack gap={4}>
            <Typography variant="label-lg">Generated domains</Typography>
            {generatedDomainData.domains?.map((domain) => (
              <Typography key={domain.name} variant="body-lg" c="carbon.8">
                {domain.name}
              </Typography>
            ))}
          </Stack>
        )}

        {attachDomain.error && (
          <Alert icon={<IconAlertCircle size={16} />} color="red">
            {getErrorMessage(attachDomain.error, true)}
          </Alert>
        )}

        <Divider mx={-24} />

        <Group justify="flex-end">
          <Button type="button" variant="default" onClick={onClose}>
            Cancel
          </Button>
          <Button
            type="submit"
            loading={attachDomain.isLoading && attachDomain.variables?.data.validate_only === false}
          >
            Attach Domain
          </Button>
        </Group>
      </Stack>
    </FormProvider>
  )
}

function DetachDomain({ privateLink, onClose }: { privateLink: PrivateLinkConnection; onClose: () => void }) {
  const { orgId, projectId } = useOrgProjectClusterIds()
  const detach = usePrivateLinkConnectionServiceDetachDomains()
  const onConfirm = async () => {
    await detach.mutateAsync({
      orgId,
      projectId,
      clusterId: privateLink.cluster_id!,
      privateLinkConnectionId: privateLink.private_link_connection_id!,
      data: {
        attach_domain_id: privateLink.attached_domains?.at(0)?.attach_domain_id!
      }
    })

    notifier.success('Domain detach request submitted successfully.')
    onClose()
  }
  return (
    <Stack>
      <Typography>
        You are about to detach the following domains from the connection <b>{privateLink.display_name}</b>:
      </Typography>

      <Stack gap={4}>
        {privateLink.attached_domains?.at(0)?.domains?.map((domain) => (
          <Typography key={domain.name} variant="body-lg" c="carbon.8">
            {domain.name}
          </Typography>
        ))}
      </Stack>

      <Group justify="flex-end">
        <Button variant="default" onClick={onClose}>
          Cancel
        </Button>
        <Button color="red" variant="light" onClick={onConfirm} loading={detach.isLoading}>
          Yes, Detach domain
        </Button>
      </Group>
    </Stack>
  )
}
