import { ActionIcon, Box, Button, Group, Menu, Paper, Stack, Tooltip } 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 { 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'

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

import { CreatePremiumAzurePrivateEndpointModal } from './CreateAzurePrivateEndpointModal'
import { DeletePremiumAzurePrivateEndpointModal } from './DeleteAzurePrivateEndpointModal'
import { EditPremiumAzurePrivateEndpointModal } from './EditAzurePrivateEndpointModal'

export const PremiumAzurePrivateEndpointPanel = 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: (response) => {
          const pending = response?.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 [editOpened, editHandlers] = useDisclosure()
  const [deleteOpened, deleteHandlers] = 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) => {
        const editable = row.endpointState === 'DISCOVERED'
        const deletable = row.endpointState !== 'DELETING' && row.endpointState !== 'DISCOVERED'

        return (
          <Menu position="bottom-end" withinPortal>
            <Menu.Target>
              <ActionIcon
                variant="subtle"
                size="input-xs"
                aria-label="Premium Azure private endpoint action dropdown menu"
                data-mp-event={MixpanelEvents.PremiumPrivateEndpoint.Operate.EnterClicked}
                data-mp-cloud-provider={CloudProviderConst.AZURE}
              >
                <IconDotsHorizontal size={16} />
              </ActionIcon>
            </Menu.Target>
            <Menu.Dropdown>
              <AccessCheck id="TidbxNetworkingUpdate">
                {({ accessible }) => (
                  <>
                    <Menu.Item
                      disabled={!accessible || !editable}
                      onClick={() => {
                        setTargetEndpoint(row)
                        editHandlers.open()
                      }}
                      data-mp-event={MixpanelEvents.PremiumPrivateEndpointDns.Enable.EnterClicked}
                      data-mp-cloud-provider={CloudProviderConst.AZURE}
                    >
                      Edit
                    </Menu.Item>
                    <Menu.Item
                      disabled={!accessible || !deletable}
                      onClick={() => {
                        setTargetEndpoint(row)
                        deleteHandlers.open()
                      }}
                      data-mp-event={MixpanelEvents.PremiumPrivateEndpoint.Delete.EnterClicked}
                      data-mp-cloud-provider={CloudProviderConst.AZURE}
                    >
                      Delete
                    </Menu.Item>
                  </>
                )}
              </AccessCheck>
            </Menu.Dropdown>
          </Menu>
        )
      }
    }
  ]

  return (
    <Paper withBorder p="xl">
      <Stack>
        <BlockHeader
          heading="Azure Private Endpoints"
          desc="Powered by Azure 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">
        <CreatePremiumAzurePrivateEndpointModal
          tidbId={tidbId}
          regionId={tidb.regionId}
          opened={createOpened}
          onClose={createHandlers.close}
          onFinish={refetch}
        />
        <EditPremiumAzurePrivateEndpointModal
          tidbId={tidbId}
          privateEndpoint={targetEndpoint}
          opened={editOpened}
          onClose={editHandlers.close}
          onFinish={refetch}
        />
        <DeletePremiumAzurePrivateEndpointModal
          tidbId={tidbId}
          connectionId={targetEndpoint?.id ?? ''}
          endpointId={targetEndpoint?.endpointId ?? ''}
          serviceName={targetEndpoint?.privateLinkService ?? ''}
          state={targetEndpoint?.endpointState}
          opened={deleteOpened}
          onClose={deleteHandlers.close}
          onFinish={refetch}
        />
      </AccessGuard>
    </Paper>
  )
})
