import { Alert, Box, Button, Group, Loader, Select, SimpleGrid } from '@tidbcloud/uikit'
import { observer } from 'mobx-react'
import { useEffect, useMemo, useState } from 'react'

import { CloudProviderConst, CloudProviderLabelConst } from 'dbaas/features/Project'
import { PremiumIpAccessEditor } from 'dbaas/screens/NextGen/premium/networking/shared/ip-access/IpAccessEditor'
import { usePremiumPublicEndpointStatusBase } from 'dbaas/screens/NextGen/premium/networking/shared/public-endpoint-status/usePremiumPublicEndpointStatus'
import { PremiumChangeRootPwd } from 'dbaas/screens/NextGen/premium/shared/password/ChangeRootPwd'
import { PremiumAnnotation } from 'dbaas/screens/NextGen/shared/model/annotation'
import { Commonv1beta1ServicePlan } from 'dbaas/services/api-clients/v2025/tidb-management/v1beta2/interface'
import { MixpanelEvents } from 'dbaas/utils/tracking'

import { ConnectionClientBlock, getDefaultRootClient, getRootClientOptions } from './connection-client'
import { ConnectionTypeTips } from './ConnectionTypeTips'
import { essentialDocLinks, useNetworkTypes, useTidbQuery } from './helpers'
import { PrivateEndpointInit, PrivateInfoBlock, usePrivateBlockData } from './private-endpoint'
import { PublicInfoBlock, usePublicBlockData } from './public-endpoint'
import { ModalMode, NetworkType } from './types'
import { useVpcPeerBlockData, VpcPeerInfoBlock } from './vpc-peer'

interface PremiumConnectModalBodyProps {
  tidbId: string
  titleHandlers: {
    update: (title: string) => void
    reset: () => void
  }
  onCancel: () => void
}

export const PremiumConnectModalBody = observer(({ tidbId, onCancel, titleHandlers }: PremiumConnectModalBodyProps) => {
  /**
   * Network type
   */
  const { networkTypeOptions: allNetworkTypeOptions, networkType, onNetworkTypeChange } = useNetworkTypes()

  const publicBlockData = usePublicBlockData({
    isTarget: networkType === 'public',
    tidbId
  })

  const privateBlockData = usePrivateBlockData({
    isTarget: networkType === 'private',
    tidbId
  })

  const tidbQuery = useTidbQuery(tidbId, {
    pollPublicEndpointBackendReachability: networkType === 'public' && publicBlockData.enabled
  })

  const { cloudProvider = '', servicePlan, regionId = '', annotations, endpoints } = tidbQuery.data || {}
  const hideVpcPeering = !!tidbQuery.data?.computed.isEssentialV2
  const privateEndpointDocLinks = tidbQuery.data?.computed.isEssentialV2 ? essentialDocLinks.private : undefined
  const networkTypeOptions = hideVpcPeering
    ? allNetworkTypeOptions.filter((option) => option.value !== NetworkType.VpcPeer)
    : allNetworkTypeOptions

  useEffect(() => {
    if (hideVpcPeering && networkType === NetworkType.VpcPeer) {
      onNetworkTypeChange(NetworkType.Private)
    }
  }, [hideVpcPeering, networkType, onNetworkTypeChange])

  const peerBlockData = useVpcPeerBlockData({
    isTarget: networkType === NetworkType.VpcPeer,
    tidbId,
    servicePlan,
    cloudProvider,
    endpoints
  })

  const pwdInited = annotations?.[PremiumAnnotation.PwdSet] === 'true'
  const caRequiredServicePlans: Commonv1beta1ServicePlan[] = [
    Commonv1beta1ServicePlan.Premium,
    Commonv1beta1ServicePlan.Premium_Reserved,
    Commonv1beta1ServicePlan.Essential_V2
  ]

  /**
   * Connection client
   */
  const [client, setClient] = useState(() => getDefaultRootClient(NetworkType.Private))

  useEffect(() => {
    const validOptions = getRootClientOptions(networkType).filter((option) => !option.disabled)

    if (!validOptions.some((option) => option.value === client)) {
      setClient(validOptions[0]?.value ?? '')
    }
  }, [client, networkType])

  /**
   * Modal content mode
   */
  const [mode, setMode] = useState<ModalMode>(ModalMode.Connect)
  const gotoConnect = () => {
    setMode(ModalMode.Connect)
    titleHandlers.reset()
    tidbQuery.refetch()
  }
  const gotoPublicInit = () => {
    setMode(ModalMode.InitPublic)
    titleHandlers.update('Configure IP')
  }
  const gotoPrivateInit = () => {
    setMode(ModalMode.InitPrivate)
    titleHandlers.update(`Create ${CloudProviderLabelConst[cloudProvider]} Private Endpoint Connection`)
  }
  const gotoSetPwd = () => {
    setMode(ModalMode.ChangePwd)
    titleHandlers.update('Set Root Password')
  }

  const publicClientVar = useMemo(() => endpoints?.find((el) => el.connectionType === 'PUBLIC'), [endpoints])
  const publicEndpointStatus = usePremiumPublicEndpointStatusBase({
    settingEnabled: publicBlockData.enabled,
    publicEndpoint: publicClientVar,
    active: mode === ModalMode.Connect && networkType === 'public' && publicBlockData.enabled
  })

  if (mode === ModalMode.InitPublic && cloudProvider) {
    return (
      <PremiumIpAccessEditor
        tidbId={tidbId}
        cidrList={publicBlockData.cidrList ?? []}
        onClose={onCancel}
        onBack={gotoConnect}
        onConfirm={() => {
          publicBlockData.query.refetch()
          gotoConnect()
        }}
      />
    )
  }

  if (mode === ModalMode.InitPrivate && cloudProvider) {
    return (
      <PrivateEndpointInit
        tidbId={tidbId}
        cloudProvider={cloudProvider}
        regionId={regionId}
        onCancel={onCancel}
        onBack={gotoConnect}
        onConfirm={() => {
          tidbQuery.refetch()
          privateBlockData.endpointsQuery.refetch()
          gotoConnect()
        }}
      />
    )
  }

  if (mode === ModalMode.ChangePwd) {
    return (
      <PremiumChangeRootPwd
        tidbId={tidbId}
        isEditMode={pwdInited}
        onDone={gotoConnect}
        onCancel={onCancel}
        renderActions={({ submitting, cancelBtn, saveBtn }) => (
          <>
            {cancelBtn}
            <Button
              variant="default"
              disabled={submitting}
              onClick={gotoConnect}
              data-mp-event={MixpanelEvents.TidbRootPassword.Update.BackClicked}
              data-mp-service-plan={Commonv1beta1ServicePlan.Premium}
            >
              Back
            </Button>
            {saveBtn}
          </>
        )}
      />
    )
  }

  const clientVarData = {
    [NetworkType.Public]: {
      host: publicClientVar?.host,
      port: publicClientVar?.port,
      userToken: ''
    },
    [NetworkType.Private]: privateBlockData.connVarData,
    [NetworkType.VpcPeer]: peerBlockData.connVarData
  }[networkType]

  const networkReady = {
    [NetworkType.Public]: publicBlockData.enabled && publicBlockData.ready && !!publicClientVar?.host,
    [NetworkType.Private]: privateBlockData.ready,
    [NetworkType.VpcPeer]: peerBlockData.ready
  }[networkType]
  const clientVisible = !!tidbQuery.data && networkReady

  return (
    <>
      {tidbQuery.isError && (
        <Box p="xl" pb={0}>
          <Alert color="red">
            <Group gap={0}>
              Oops, something went wrong when getting connection configurations.
              <Button
                variant="white"
                color="peacock"
                onClick={() => tidbQuery.refetch()}
                loading={tidbQuery.isRefetching}
                bg="transparent"
                fw={600}
                h={20}
                px={4}
                data-mp-event={MixpanelEvents.TidbConnect.Retry.ButtonClicked}
                data-mp-service-plan={Commonv1beta1ServicePlan.Premium}
              >
                Retry
              </Button>
            </Group>
          </Alert>
        </Box>
      )}
      <SimpleGrid cols={1} p="xl">
        <Select
          label={<ConnectionTypeTips hideVpcPeering={hideVpcPeering} />}
          value={networkType}
          data={networkTypeOptions}
          disabled={tidbQuery.isLoading}
          rightSection={tidbQuery.isLoading ? <Loader size="xs" /> : undefined}
          onChange={onNetworkTypeChange}
          data-testid="premium-connect-network-type-select"
        />
      </SimpleGrid>
      {networkType === 'public' && (
        <PublicInfoBlock
          tidbId={tidbId}
          cloudProvider={cloudProvider}
          loading={tidbQuery.isLoading || publicBlockData.loading}
          enabled={publicBlockData.enabled}
          endpointReady={publicEndpointStatus.endpointReady}
          ipList={publicBlockData.ipList}
          onCancel={onCancel}
          onInit={gotoPublicInit}
        />
      )}
      {networkType === 'private' && (
        <PrivateInfoBlock
          loading={privateBlockData.loading}
          tidbId={tidbId}
          cloudProvider={cloudProvider}
          fullData={privateBlockData.fullEndpoints}
          activeData={privateBlockData.activeEndpoints}
          endpointId={privateBlockData.endpointId}
          docLinks={privateEndpointDocLinks}
          onEndpointChange={privateBlockData.onEndpointChange}
          onCancel={onCancel}
          onInit={gotoPrivateInit}
        />
      )}
      {networkType === 'peering' && (
        <VpcPeerInfoBlock
          tidbId={tidbId}
          supported={
            (servicePlan === Commonv1beta1ServicePlan.BYOC && cloudProvider === CloudProviderConst.AWS) ||
            servicePlan === Commonv1beta1ServicePlan.Premium
          }
          showCreateButton={servicePlan === Commonv1beta1ServicePlan.BYOC}
          loading={peerBlockData.loading}
          data={peerBlockData.vpcPeerings}
          onCancel={onCancel}
        />
      )}
      {clientVisible && (
        <ConnectionClientBlock
          tidbId={tidbId}
          pwdInited={pwdInited}
          networkType={networkType}
          client={client}
          onClientChange={setClient}
          onPwdSet={gotoSetPwd}
          caRequired={!!servicePlan && caRequiredServicePlans.includes(servicePlan) && networkType === 'public'}
          servicePlan={servicePlan}
          host={clientVarData.host}
          port={clientVarData.port}
          userToken={clientVarData.userToken}
        />
      )}
    </>
  )
})
