import { Button, Card, Modal, Stack } from '@tidbcloud/uikit'
import { useDisclosure } from '@tidbcloud/uikit/hooks'
import { useMemo } from 'react'

import { ReasonHoverHint, type HoverHintReason } from 'dbaas/components/HoverHint/ReasonHoverHint'
import { AccessGuard, useAccessDeniedHintReason } from 'dbaas/contexts/access-control'
import { CloudProviderConst } from 'dbaas/features/Project'
import { BlockHeader } from 'dbaas/screens/NextGen/premium/networking/shared/BlockHeader'
import { getTidbStateToPassivePhrase } from 'dbaas/screens/NextGen/shared/model/tidb-state'
import { useSharedTiDBContext } from 'dbaas/screens/NextGen/tidb-mgmt-container/shared/tidb-context'
import { useNgListSinkEndpoints } from 'dbaas/services/dataflow'

import { CreatePrivateEndpointForChangefeed } from './Create'
import { PrivateEndpointForChangefeedList } from './List'

export const PremiumPrivateEndpointForChangefeed = () => {
  const cluster = useSharedTiDBContext()
  const [opened, handler] = useDisclosure()
  const shouldFetchSinkEndpoints =
    (cluster.computed.isPremium ||
      cluster.computed.isPremiumReserved ||
      cluster.computed.isBYOC ||
      cluster.computed.isEssentialV2) &&
    !!cluster.tidbId
  const { data, refetch } = useNgListSinkEndpoints(cluster.tidbId!, undefined, {
    query: {
      enabled: shouldFetchSinkEndpoints
    }
  })

  const [title, description] = useMemo(() => {
    let title = 'Private Endpoints for External Services'
    let desc =
      '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.'
    if (cluster.cloudProvider === CloudProviderConst.AWS) {
      title = 'AWS Private Endpoints for External Services'
      desc =
        '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.'
    } else if (cluster.cloudProvider === CloudProviderConst.GCP) {
      title = 'Google Cloud Private Endpoints for External Services'
    } else if (cluster.cloudProvider === CloudProviderConst.AZURE) {
      title = 'Azure Private Endpoints for External Services'
    } else if (cluster.cloudProvider === CloudProviderConst.ALICLOUD) {
      title = 'Alibaba Cloud Private Endpoints for External Services'
    }

    return [title, desc]
  }, [cluster.cloudProvider])

  const { reason: accessDeniedReason } = useAccessDeniedHintReason({
    id: 'TidbxCDCAction',
    scopeProps: { tidbId: cluster.tidbId }
  })
  const tidbReady = cluster.computed.ready
  const passivePhrase = getTidbStateToPassivePhrase(cluster.state)
  const notReadyReason: HoverHintReason = useMemo(
    () => ({
      id: 'notReady',
      when: !tidbReady,
      content: `This feature is unavailable while the instance is ${passivePhrase}.`
    }),
    [passivePhrase, tidbReady]
  )

  return (
    <Card p="xl" component={Stack}>
      <BlockHeader
        heading={title}
        desc={description}
        rightSection={
          <ReasonHoverHint reasons={[accessDeniedReason, notReadyReason]}>
            {({ matched }) => (
              <Button size="sm" variant="default" disabled={matched} onClick={handler.open}>
                Create Private Endpoint for External Services
              </Button>
            )}
          </ReasonHoverHint>
        }
      />

      {data && !!data.sink_endpoints?.length && <PrivateEndpointForChangefeedList cluster={cluster} />}

      <AccessGuard id="TidbxCDCAction">
        <Modal
          title="Create Private Endpoint for External Services"
          opened={opened}
          onClose={handler.close}
          size="xl"
          closeOnClickOutside={false}
        >
          <CreatePrivateEndpointForChangefeed
            cluster={cluster}
            onCancel={() => {
              handler.close()
              refetch()
            }}
          />
        </Modal>
      </AccessGuard>
    </Card>
  )
}
