import { Box } from '@tidbcloud/uikit'
import { useRafInterval, useUnmount } from 'ahooks'
import { observer } from 'mobx-react'
import { useEffect, useMemo } from 'react'
import { Redirect, useLocation, useParams } from 'react-router-dom'

import { PageLoader } from 'dbaas/components/Placeholder'
import { PageAccessGuard } from 'dbaas/contexts/access-control'
import { getSharedCluster } from 'dbaas/features/ClusterManagement/cluster'
import { getSharedTiDB } from 'dbaas/screens/NextGen/shared/model/shared-tidb-state'
import { CONNECT_MODAL_QUERY_VALUE, OPEN_MODAL_QUERY_KEY } from 'dbaas/screens/NextGen/shared/query-params'
import { useTiDBServiceGetTidb } from 'dbaas/services/api-clients/v2023/cluster-management/v1beta2'
import { TidbCloudOpenApinextgenv1beta2Tidb } from 'dbaas/services/api-clients/v2025/tidb-management/v1beta2/interface'
import useStores from 'dbaas/stores/useStores'

import { useClusterDashboard, useClusterStatusHandler, useNavbarHidden } from '../../ClusterV2/Container/helpers'
import Navbar from '../../ClusterV2/Container/Navbar'
import ClusterRoutes from '../../ClusterV2/Container/Routes'
import { EssentialV2Nav, EssentialV2Routes } from '../essential/Routes'

import { TiDBMgmtNav, TiDBMgmtRoutes } from './Routes'

const DEFAULT_POLLING_INTERVAL = 20 * 1000
const FAST_POLLING_INTERVAL = 3 * 1000

export const TidbMgmtContainer = observer(() => {
  const { id: tidbId } = useParams<{ id: string }>()
  const location = useLocation()
  const {
    store: { tenantData },
    actions: { setCurrentTiDB, setCurrentCluster, updateLastVisitLocation }
  } = useStores()

  const navbarHidden = useNavbarHidden()
  const updateDashboardConfig = useClusterDashboard()
  const clusterStatusHandler = useClusterStatusHandler()
  const orgId = tenantData.id

  const {
    data: tidbData,
    isLoading,
    isError,
    refetch
  } = useTiDBServiceGetTidb(
    tidbId,
    {
      orgId
    },
    {
      query: {
        enabled: !!tidbId && !!orgId,
        staleTime: 30 * 1000
      }
    }
  )

  // Determine which type of data we have
  const isSharedTiDBInstance = useMemo(() => {
    return !!(
      tidbData?.byocInstance ||
      tidbData?.premiumInstance ||
      tidbData?.essentialV2Instance ||
      tidbData?.premiumReservedInstance
    )
  }, [tidbData])

  // Convert data based on type
  const sharedTiDB = useMemo(() => {
    if (!tidbData) return null
    const instanceSource = (tidbData.byocInstance ||
      tidbData.premiumInstance ||
      tidbData.essentialV2Instance ||
      tidbData.premiumReservedInstance ||
      null) as TidbCloudOpenApinextgenv1beta2Tidb | null

    if (instanceSource) {
      return getSharedTiDB(instanceSource, {
        originalProjectId: tidbData.originalProjectId || ''
      })
    }
    return null
  }, [tidbData])

  const sharedCluster = useMemo(() => {
    if (!tidbData) return null
    if (tidbData.essentialInstance || tidbData.starterInstance || tidbData.dedicatedCluster) {
      return getSharedCluster(
        tidbData.essentialInstance || tidbData.starterInstance || tidbData.dedicatedCluster || null,
        { originalProjectId: tidbData.originalProjectId || '' }
      )
    }
    return null
  }, [tidbData])

  const data = sharedTiDB || sharedCluster
  const shouldOpenConnectFromQuery = useMemo(() => {
    const params = new URLSearchParams(location.search)
    return params.get(OPEN_MODAL_QUERY_KEY) === CONNECT_MODAL_QUERY_VALUE
  }, [location.search])
  const shouldUseFastPolling =
    !!sharedCluster &&
    !isSharedTiDBInstance &&
    shouldOpenConnectFromQuery &&
    (sharedCluster.computed.creating || sharedCluster.computed.recovering)

  // Handle Premium/BYOC logic
  useEffect(() => {
    if (sharedTiDB) {
      setCurrentTiDB(sharedTiDB)
      if (sharedTiDB.computed.projectId) {
        updateLastVisitLocation({
          orgId,
          projectId: sharedTiDB.computed.projectId
        })
      }
    }
  }, [orgId, sharedTiDB, setCurrentTiDB, updateLastVisitLocation])

  // Handle Starter/Essential logic (similar to Shell.tsx)
  useEffect(() => {
    if (sharedCluster) {
      clusterStatusHandler(sharedCluster)
      setCurrentCluster(sharedCluster)
      updateDashboardConfig(sharedCluster)
      if (sharedCluster.computed.projectId) {
        updateLastVisitLocation({
          orgId,
          projectId: sharedCluster.computed.projectId
        })
      }
    }
  }, [clusterStatusHandler, orgId, setCurrentCluster, sharedCluster, updateDashboardConfig, updateLastVisitLocation])

  // For Starter/Essential, use useRafInterval for polling (similar to Shell.tsx)
  useRafInterval(
    () => {
      if (sharedCluster && !isSharedTiDBInstance) {
        refetch()
      }
    },
    !isSharedTiDBInstance && sharedCluster
      ? shouldUseFastPolling
        ? FAST_POLLING_INTERVAL
        : DEFAULT_POLLING_INTERVAL
      : undefined,
    {
      immediate: shouldUseFastPolling
    }
  )

  useUnmount(() => {
    if (isSharedTiDBInstance) {
      setCurrentTiDB(null)
    } else {
      setCurrentCluster(null)
    }
  })

  if (!tidbId) {
    return <Redirect to="/tidbs" />
  }

  if (!orgId || isLoading) {
    return <PageLoader />
  }

  if (isError || !data) {
    return <Redirect to="/tidbs" />
  }

  // Essential V2 has its own layout map: Essential overview/integrations plus Premium feature pages.
  if (isSharedTiDBInstance && sharedTiDB?.computed.isEssentialV2) {
    return (
      <PageAccessGuard id="TidbxRead">
        <EssentialV2Nav tidb={sharedTiDB} />
        <EssentialV2Routes tidb={sharedTiDB} />
      </PageAccessGuard>
    )
  }

  // For Premium/BYOC, use TiDBMgmtNav + TiDBMgmtRoutes
  if (isSharedTiDBInstance && sharedTiDB) {
    return (
      <PageAccessGuard id="TidbxRead">
        <TiDBMgmtNav tidb={sharedTiDB} />
        <TiDBMgmtRoutes tidb={sharedTiDB} />
      </PageAccessGuard>
    )
  }

  // For Starter/Essential, use Navbar + ClusterRoutes (Shell.tsx logic)
  if (!isSharedTiDBInstance && sharedCluster) {
    const content = (
      <Box h="100%">
        <Navbar hidden={navbarHidden} cluster={sharedCluster} />
        <ClusterRoutes cluster={sharedCluster} />
      </Box>
    )

    if (sharedCluster.computed.isStarter || sharedCluster.computed.isEssential) {
      return <PageAccessGuard id="TidbxRead">{content}</PageAccessGuard>
    }

    return content
  }

  return <Redirect to="/tidbs" />
})
