import { Group, Button, Menu, ActionIcon, Tooltip, Box, Stack, Paper } from '@tidbcloud/uikit'
import { MRT_ColumnDef, ProTable } from '@tidbcloud/uikit/biz'
import { useDisclosure } from '@tidbcloud/uikit/hooks'
import { IconDotsHorizontal, IconInfoCircle } from '@tidbcloud/uikit/icons'
import { observer } from 'mobx-react'
import { useEffect, useMemo, useState } from 'react'

import { ReasonHoverHint, type HoverHintReason } from 'dbaas/components/HoverHint/ReasonHoverHint'
import { AccessCheck, 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 { usePrivateEndpointConnectionServiceListPrivateEndpointConnections } from 'dbaas/services/api-clients/v2025/tidb-management/v1beta2'
import { Nextgenv1beta2PrivateEndpointConnection } from 'dbaas/services/api-clients/v2025/tidb-management/v1beta2/interface'
import useStores from 'dbaas/stores/useStores'
import { MixpanelEvents } from 'dbaas/utils/tracking/event'

import { ServiceStatusBadge } from '../shared/ServiceStatusBadge'

import { CreatePremiumAwsPrivateEndpointModal } from './CreateAwsPrivateEndpointModal'
import { DeletePremiumAwsPrivateEndpointModal } from './DeleteAwsPrivateEndpointModal'
import { PremiumEnableAwsDnsGuideModal } from './EnableAwsDnsGuideModal'

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

  const tidb = useSharedTiDBContext()
  const tidbId = tidb.tidbId!
  const passivePhrase = getTidbStateToPassivePhrase(tidb?.state)
  const { reason: accessDeniedReason } = useAccessDeniedHintReason({ id: 'TidbxNetworkingUpdate' })
  const notReadyReason = useMemo<HoverHintReason>(
    () => ({
      id: 'notReady',
      when: !tidb?.computed.ready,
      content: `This feature is unavailable while the instance is ${passivePhrase}.`
    }),
    [passivePhrase, tidb?.computed.ready]
  )
  const { data, isLoading, refetch } = usePrivateEndpointConnectionServiceListPrivateEndpointConnections(
    tidbId,
    {
      orgId,
      projectId
    },
    {
      query: {
        refetchInterval: (data) => {
          const pending = data?.privateEndpointConnections?.some(
            (el) => el.endpointState === 'PENDING' || el.privateLinkServiceState === 'CREATING'
          )

          return pending ? 20 * 1000 : false
        }
      }
    }
  )
  const privateEndpointConnections = data?.privateEndpointConnections ?? []
  const [pagination, setPagination] = useState({
    pageIndex: 0,
    pageSize: 5
  })
  useEffect(() => {
    setPagination((prev) => {
      const maxPageIndex = Math.max(Math.ceil(privateEndpointConnections.length / prev.pageSize) - 1, 0)

      return prev.pageIndex > maxPageIndex ? { ...prev, pageIndex: maxPageIndex } : prev
    })
  }, [privateEndpointConnections.length, pagination.pageSize])
  const paginatedPrivateEndpointConnections = privateEndpointConnections.slice(
    pagination.pageIndex * pagination.pageSize,
    (pagination.pageIndex + 1) * pagination.pageSize
  )

  const [targetEndpoint, setTargetEndpoint] = useState<Nextgenv1beta2PrivateEndpointConnection>()
  const [createOpened, createHandlers] = useDisclosure()
  const [deleteOpened, deleteHandlers] = useDisclosure()
  const [dnsGuideOpened, dnsGuideHandlers] = useDisclosure()

  const columns: MRT_ColumnDef<Nextgenv1beta2PrivateEndpointConnection>[] = [
    {
      id: 'privateLinkService',
      header: 'TiDB Endpoint Service',
      accessorFn: (row) => <Box sx={{ wordBreak: 'break-all' }}>{row.privateLinkService}</Box>,
      mantineTableHeadCellProps: {
        pl: 'md'
      },
      mantineTableBodyCellProps: {
        pl: 'md'
      }
    },
    {
      id: 'privateLinkServiceState',
      header: 'Service Status',
      accessorFn: (row) => <ServiceStatusBadge status={row.privateLinkServiceState} />,
      size: 120
    },
    {
      header: 'Private Endpoint',
      accessorKey: 'endpointId'
    },
    {
      id: 'endpointState',
      header: 'Endpoint Status',
      accessorFn: (row) => (
        <Group gap={8}>
          <ServiceStatusBadge status={row.endpointState} />
          {row.endpointState === 'FAILED' && row.message && (
            <Tooltip label={row.message}>
              <IconInfoCircle />
            </Tooltip>
          )}
        </Group>
      ),
      size: 120
    },
    {
      id: 'operations',
      header: '',
      size: 56,
      accessorFn: (row) => (
        <Menu position="bottom-end" withinPortal>
          <Menu.Target>
            <ActionIcon
              variant="subtle"
              size="input-xs"
              aria-label="Premium AWS private endpoint action dropdown menu"
              data-mp-event={MixpanelEvents.PremiumPrivateEndpoint.Operate.EnterClicked}
              data-mp-cloud-provider={CloudProviderConst.AWS}
            >
              <IconDotsHorizontal size={16} />
            </ActionIcon>
          </Menu.Target>
          <Menu.Dropdown>
            <Menu.Item
              onClick={() => {
                setTargetEndpoint(row)
                dnsGuideHandlers.open()
              }}
              data-mp-event={MixpanelEvents.PremiumPrivateEndpointDns.Enable.EnterClicked}
              data-mp-cloud-provider={CloudProviderConst.AWS}
            >
              Enable DNS
            </Menu.Item>
            <AccessCheck id="TidbxNetworkingUpdate">
              {({ accessible }) => (
                <Menu.Item
                  disabled={!accessible}
                  onClick={() => {
                    setTargetEndpoint(row)
                    deleteHandlers.open()
                  }}
                  data-mp-event={MixpanelEvents.PremiumPrivateEndpoint.Delete.EnterClicked}
                  data-mp-cloud-provider={CloudProviderConst.AWS}
                >
                  Delete
                </Menu.Item>
              )}
            </AccessCheck>
          </Menu.Dropdown>
        </Menu>
      )
    }
  ]

  return (
    <Paper withBorder p="xl">
      <Stack>
        <BlockHeader
          heading="AWS Private Endpoints"
          desc="Powered by AWS PrivateLink, Private Endpoints enable secure and private connectivity to your instance without exposing traffic to the public internet."
          rightSection={
            <ReasonHoverHint reasons={[accessDeniedReason, notReadyReason]}>
              {({ matched }) => (
                <Button variant="default" size="sm" disabled={matched} onClick={createHandlers.open}>
                  Create Private Endpoint Connection
                </Button>
              )}
            </ReasonHoverHint>
          }
        />
        {(isLoading || privateEndpointConnections.length > 0) && (
          <ProTable
            columns={columns}
            emptyMessage="No Data"
            loading={isLoading}
            data={paginatedPrivateEndpointConnections}
            manualPagination
            pagination={{
              showRowsPerPage: true,
              showTotal: true
            }}
            state={{ pagination }}
            onPaginationChange={setPagination}
            rowCount={privateEndpointConnections.length}
          />
        )}
      </Stack>
      <AccessGuard id="TidbxNetworkingUpdate">
        <CreatePremiumAwsPrivateEndpointModal
          tidbId={tidbId}
          regionId={tidb.regionId}
          opened={createOpened}
          onClose={createHandlers.close}
          onFinish={refetch}
        />
        <DeletePremiumAwsPrivateEndpointModal
          tidbId={tidbId}
          connectionId={targetEndpoint?.id ?? ''}
          endpointName={targetEndpoint?.name ?? ''}
          opened={deleteOpened}
          onClose={deleteHandlers.close}
          onFinish={refetch}
        />
      </AccessGuard>
      <PremiumEnableAwsDnsGuideModal
        endpointId={targetEndpoint?.endpointId ?? ''}
        regionId={targetEndpoint?.regionId ?? ''}
        opened={dnsGuideOpened}
        onClose={dnsGuideHandlers.close}
      />
    </Paper>
  )
})
