import React from 'react'
import { useEffect, useMemo, useRef, useState } from 'react'

import useUrlState from '@ahooksjs/use-url-state'
import { BrushEndListener, BrushEvent } from '@elastic/charts'
import {
  SelectProps,
  Alert,
  Badge,
  Box,
  Card,
  Flex,
  Grid,
  Group,
  SegmentedControl,
  Select,
  Stack,
  Title,
  Typography,
  useMantineTheme
} from '@tidbcloud/uikit'
import {
  fromTimeRangeValue,
  TimeRange,
  TimeRangePicker,
  toTimeRangeValue,
  toURLTimeRange,
  urlToTimeRange
} from '@tidbcloud/uikit/biz'
import { useElementSize } from '@tidbcloud/uikit/hooks'
import dayjs from 'dayjs'

import { ngmContextFromCluster } from '~/api/ngm'
import { useCurCluster, useCurOrg } from '~/hooks/state'
import { ClusterDeployTypeV2 } from '~/utils/cluster-status'

import AutoRefreshButton, {
  AutoRefreshButtonRef
} from './_shared/AutoRefreshButton'
import {
  useTopruSummaryPlanQuery,
  useTopruSummaryQuery,
  useTopruUserStatsQuery
} from './_shared/hooks'
import { eventTracking } from './_shared/tracking'
import {
  TOP_SQL_TREND_COLOR_ALPHAS,
  TOP_SQL_TREND_COLOR_NAMES,
  TOP_SQL_TREND_COLOR_SHADE,
  withAlpha
} from './colors'
import {
  getTopSQLUserLabel,
  getTopSQLUserOptionValue,
  getTopSQLUserRequestValue,
  isTopSQLSystemInternalUserValue
} from './constants'
import { resolveTopSQLIdentity } from './display'
import { onLegendItemOut, onLegendItemOver } from './legendAction'
import SQLExecutionPlanDrawer from './SQLExecutionPlanDrawer'
import TopSQLTable from './TopSQLTable'
import { buildTopSQLExecutionPlans, fillTrendPointGaps } from './transform'
import TrendChart from './TrendChart'
import {
  TopRUSummaryItem,
  TopRUSummaryResponse,
  TopSQLExecutionPlanAnalysisResponse,
  TopSQLTableRecord,
  TopSQLViewMode
} from './types'
import UserShareCard from './UserShareCard'

const QUICK_RANGES = [
  15 * 60,
  30 * 60,
  60 * 60,
  2 * 60 * 60,
  6 * 60 * 60,
  12 * 60 * 60,
  24 * 60 * 60
]
const DEFAULT_TOP_LIMIT = 10
const LIMIT_VALUES = [5, 10, 20, 100] as const
const buildLimitOptions = (maxTop: number) =>
  LIMIT_VALUES.filter((value) => value <= maxTop).map((value) => ({
    value: `${value}`,
    label: `Top ${value}`
  }))
const AUTO_REFRESH_OPTIONS = [60, 300]
const DEFAULT_TREND_CHART_WIDTH = 720
const TREND_BAR_WIDTH_PX = 6
const ONE_DAY_SECONDS = 24 * 60 * 60
const MAX_CUSTOM_RANGE_SECONDS = 1 * ONE_DAY_SECONDS
const TOP_RU_TIER_CONFIG = {
  premium: {
    maxHistoryDays: 30,
    maxTop: 100
  },
  essential: {
    maxHistoryDays: 7,
    maxTop: 20
  }
} as const
const MIN_SUMMARY_STEP_SECONDS = 1
const SUMMARY_STEP_CANDIDATES = [
  1,
  2,
  5,
  10,
  15,
  30,
  60,
  2 * 60,
  5 * 60,
  10 * 60,
  15 * 60,
  30 * 60,
  60 * 60,
  2 * 60 * 60,
  3 * 60 * 60,
  6 * 60 * 60,
  12 * 60 * 60,
  24 * 60 * 60
] as const
const DEFAULT_TIME_RANGE: TimeRange = {
  type: 'relative',
  value: 60 * 60
}
const DEFAULT_TOP_SQL_AUTO_REFRESH_SECONDS = 0

type TimeRangeValue = ReturnType<typeof toTimeRangeValue>

const normalizeTopLimit = (value: string | undefined, maxTop: number) => {
  const parsedTop = Number(value)
  if (Number.isFinite(parsedTop)) {
    if (parsedTop > maxTop) {
      return `${maxTop}`
    }
    if ((LIMIT_VALUES as readonly number[]).includes(parsedTop)) {
      return `${parsedTop}`
    }
  }

  return `${Math.min(DEFAULT_TOP_LIMIT, maxTop)}`
}

const isSameTimeRangeValue = (left: TimeRangeValue, right: TimeRangeValue) =>
  left[0] === right[0] && left[1] === right[1]

const normalizeTimeRangeValue = (
  value: TimeRangeValue,
  maxHistoryDays: number
): TimeRangeValue => {
  const now = dayjs().unix()
  const minTimestamp = dayjs()
    .subtract(maxHistoryDays, 'day')
    .startOf('day')
    .unix()
  const rawStart = Math.floor(value[0])
  const rawEnd = Math.ceil(value[1])

  if (
    !Number.isFinite(rawStart) ||
    !Number.isFinite(rawEnd) ||
    rawStart >= rawEnd
  ) {
    return [now - DEFAULT_TIME_RANGE.value, now] as TimeRangeValue
  }

  const nextEnd = Math.min(rawEnd, now)
  let nextStart = Math.max(rawStart, minTimestamp)

  if (nextEnd <= minTimestamp) {
    return [
      Math.max(minTimestamp, now - DEFAULT_TIME_RANGE.value),
      now
    ] as TimeRangeValue
  }

  if (nextStart >= nextEnd) {
    nextStart = Math.max(minTimestamp, nextEnd - DEFAULT_TIME_RANGE.value)
  }

  return [nextStart, nextEnd] as TimeRangeValue
}

const renderUserOption: SelectProps['renderOption'] = ({ option }) => (
  <Typography
    variant='body-lg'
    fs={isTopSQLSystemInternalUserValue(option.value) ? 'italic' : undefined}
  >
    {option.label}
  </Typography>
)

interface Filters {
  view: TopSQLViewMode
  top: string
  user: string
  from: string
  to: string
}

const getTopRURecordKey = (sqlDigest?: string) => sqlDigest || '-'

const normalizeSummaryResponse = (
  payload?: TopRUSummaryResponse | TopRUSummaryItem[]
) => {
  if (Array.isArray(payload)) {
    return {
      items: payload,
      step: undefined
    }
  }

  return {
    items: payload?.data || [],
    step: payload?.step
  }
}

const parseStepSeconds = (step?: number) => {
  if (typeof step === 'number' && Number.isFinite(step) && step > 0) {
    return Math.max(MIN_SUMMARY_STEP_SECONDS, Math.floor(step))
  }
}

const getSummaryStepSeconds = (
  timeRangeSeconds: number,
  chartWidth: number
) => {
  const safeRangeSeconds = Math.max(MIN_SUMMARY_STEP_SECONDS, timeRangeSeconds)
  const safeWidth = Math.max(
    chartWidth || DEFAULT_TREND_CHART_WIDTH,
    TREND_BAR_WIDTH_PX
  )
  const targetBarCount = Math.max(1, Math.floor(safeWidth / TREND_BAR_WIDTH_PX))
  const rawStepSeconds = Math.ceil(safeRangeSeconds / targetBarCount)

  return (
    SUMMARY_STEP_CANDIDATES.find((candidate) => candidate >= rawStepSeconds) ||
    rawStepSeconds
  )
}

const TopRUPageContent: React.FC = () => {
  const { curCluster: cluster } = useCurCluster()
  const { curOrg } = useCurOrg()
  const orgId = curOrg?.id || ''
  const orgExternalId = curOrg?.externalID || ''
  const ngmCtx = useMemo(
    () => (cluster ? ngmContextFromCluster(cluster, orgExternalId) : null),
    [cluster, orgExternalId]
  )
  const [{ view, top, user, from, to }, setFilters] = useUrlState<
    Partial<Filters>
  >(
    {
      view: 'overview',
      top: `${DEFAULT_TOP_LIMIT}`,
      user: undefined,
      from: undefined,
      to: undefined
    },
    { navigateMode: 'replace' }
  )
  const topRuConfig = useMemo(
    () =>
      cluster?.computed.isEssential ||
      cluster?.deployTypeV2 === ClusterDeployTypeV2.EssentialV2
        ? TOP_RU_TIER_CONFIG.essential
        : TOP_RU_TIER_CONFIG.premium,
    [cluster?.computed.isEssential, cluster?.deployTypeV2]
  )
  const limitOptions = useMemo(
    () => buildLimitOptions(topRuConfig.maxTop),
    [topRuConfig.maxTop]
  )
  const normalizedTop = useMemo(
    () => normalizeTopLimit(top, topRuConfig.maxTop),
    [top, topRuConfig.maxTop]
  )
  const autoRefreshRef = useRef<AutoRefreshButtonRef>(null)
  const trendChartRef = useRef<any>(null)
  const { ref: trendChartSizeRef, width: trendChartWidth } = useElementSize()
  const { colors } = useMantineTheme()
  const [hoveredKey, setHoveredKey] = useState<string>()
  const [selectedRecordKey, setSelectedRecordKey] = useState<string>()
  const [analysisContext, setAnalysisContext] = useState<{
    record: TopSQLTableRecord
    rank: number
  } | null>(null)
  const [autoRefreshValue, setAutoRefreshValue] = useState<number>(
    DEFAULT_TOP_SQL_AUTO_REFRESH_SECONDS
  )

  const timeRange = useMemo(() => {
    if (from && to) {
      return urlToTimeRange({ from, to })
    }

    return DEFAULT_TIME_RANGE
  }, [from, to])

  const [queryTimeRangeValue, setQueryTimeRangeValue] = useState<
    ReturnType<typeof toTimeRangeValue>
  >(() =>
    normalizeTimeRangeValue(
      toTimeRangeValue(timeRange),
      topRuConfig.maxHistoryDays
    )
  )
  const [displayedTrendTimeRangeValue, setDisplayedTrendTimeRangeValue] =
    useState<ReturnType<typeof toTimeRangeValue>>(() =>
      normalizeTimeRangeValue(
        toTimeRangeValue(timeRange),
        topRuConfig.maxHistoryDays
      )
    )
  const [displayedSummaryStepSeconds, setDisplayedSummaryStepSeconds] =
    useState(() =>
      getSummaryStepSeconds(
        queryTimeRangeValue[1] - queryTimeRangeValue[0],
        DEFAULT_TREND_CHART_WIDTH
      )
    )

  const resetAutoRefreshCountdown = () => {
    autoRefreshRef.current?.resetCountdown()
  }

  useEffect(() => {
    if (top && top !== normalizedTop) {
      setFilters({ top: normalizedTop })
    }
  }, [normalizedTop, setFilters, top])

  useEffect(() => {
    const rawTimeRangeValue = toTimeRangeValue(timeRange)
    const normalizedTimeRangeValue = normalizeTimeRangeValue(
      rawTimeRangeValue,
      topRuConfig.maxHistoryDays
    )

    setQueryTimeRangeValue(normalizedTimeRangeValue)

    if (
      from &&
      to &&
      !isSameTimeRangeValue(rawTimeRangeValue, normalizedTimeRangeValue)
    ) {
      setFilters(toURLTimeRange(fromTimeRangeValue(normalizedTimeRangeValue)))
    }
  }, [from, setFilters, timeRange, to, topRuConfig.maxHistoryDays])

  const topruUserStatsQuery = useTopruUserStatsQuery(
    ngmCtx,
    {
      start: String(queryTimeRangeValue[0]),
      end: String(queryTimeRangeValue[1]),
      top: '20'
    },
    {
      enabled: !!orgId && !!ngmCtx?.clusterId,
      refetchOnWindowFocus: false,
      keepPreviousData: true
    }
  )

  const userShareItems = useMemo(
    () =>
      (topruUserStatsQuery.data?.data || [])
        .map((item) => ({
          key: getTopSQLUserOptionValue(item.user),
          label: getTopSQLUserLabel(item.user),
          ru: item.total_ru || 0
        }))
        .sort((left, right) => right.ru - left.ru),
    [topruUserStatsQuery.data]
  )

  const userShareTotalRU = useMemo(
    () => userShareItems.reduce((sum, item) => sum + item.ru, 0),
    [userShareItems]
  )
  const userFilterOptions = useMemo(
    () =>
      (topruUserStatsQuery.data?.data || [])
        .map((item) => ({
          value: getTopSQLUserOptionValue(item.user),
          label: getTopSQLUserLabel(item.user)
        }))
        .filter(
          (item, index, items) =>
            items.findIndex((candidate) => candidate.value === item.value) ===
            index
        ),
    [topruUserStatsQuery.data]
  )
  const selectedUser = useMemo(() => {
    if ((view || 'overview') !== 'users') {
      return undefined
    }

    return userFilterOptions.find((option) => option.value === user)?.value
  }, [user, userFilterOptions, view])

  useEffect(() => {
    if ((view || 'overview') !== 'users') {
      return
    }

    if (!userFilterOptions.length) {
      return
    }

    const matchedUser = userFilterOptions.some(
      (option) => option.value === user
    )
    if (!matchedUser) {
      setFilters({ user: userFilterOptions[0].value })
    }
  }, [setFilters, user, userFilterOptions, view])

  useEffect(() => {
    setAnalysisContext(null)
  }, [selectedUser, view])

  const requestedSummaryStepSeconds = useMemo(
    () =>
      getSummaryStepSeconds(
        queryTimeRangeValue[1] - queryTimeRangeValue[0],
        trendChartWidth
      ),
    [queryTimeRangeValue, trendChartWidth]
  )
  const requestedUser = useMemo(() => {
    if ((view || 'overview') !== 'users') {
      return undefined
    }

    return getTopSQLUserRequestValue(selectedUser)
  }, [selectedUser, view])
  const topruSummaryParams = useMemo(
    () => ({
      start: String(queryTimeRangeValue[0]),
      end: String(queryTimeRangeValue[1]),
      top: normalizedTop,
      order_by: 'ru',
      step: requestedSummaryStepSeconds,
      ...(requestedUser !== undefined ? { user: requestedUser } : {})
    }),
    [
      normalizedTop,
      queryTimeRangeValue,
      requestedSummaryStepSeconds,
      requestedUser
    ]
  )
  const topruSummaryQuery = useTopruSummaryQuery(ngmCtx, topruSummaryParams, {
    enabled:
      !!orgId &&
      !!ngmCtx?.clusterId &&
      ((view || 'overview') !== 'users' || selectedUser !== undefined),
    refetchOnWindowFocus: false,
    keepPreviousData: true
  })
  const shouldFetchSummaryPlans =
    !!analysisContext &&
    !analysisContext.record.isOthers &&
    !!analysisContext.record.digest
  const topruSummaryPlanParams = useMemo(
    () => ({
      start: String(displayedTrendTimeRangeValue[0]),
      end: String(displayedTrendTimeRangeValue[1]),
      top: normalizedTop,
      digest: analysisContext?.record.digest,
      order_by: 'ru',
      step: displayedSummaryStepSeconds,
      ...(requestedUser !== undefined ? { user: requestedUser } : {})
    }),
    [
      analysisContext?.record.digest,
      displayedSummaryStepSeconds,
      displayedTrendTimeRangeValue,
      normalizedTop,
      requestedUser
    ]
  )
  const topruSummaryPlanQuery = useTopruSummaryPlanQuery(
    ngmCtx,
    topruSummaryPlanParams,
    {
      enabled: shouldFetchSummaryPlans && !!orgId && !!ngmCtx?.clusterId,
      refetchOnWindowFocus: false
    }
  )

  const topruSummaryData = topruSummaryQuery.data
  const normalizedSummary = useMemo(
    () =>
      normalizeSummaryResponse(
        topruSummaryData?.data as
          | TopRUSummaryResponse
          | TopRUSummaryItem[]
          | undefined
      ),
    [topruSummaryData]
  )
  const summaryItems = normalizedSummary.items
  const summaryPlanItems = useMemo(
    () => topruSummaryPlanQuery.data?.data || [],
    [topruSummaryPlanQuery.data]
  )
  const resolvedSummaryStepSeconds = useMemo(
    () =>
      parseStepSeconds(normalizedSummary.step) || requestedSummaryStepSeconds,
    [normalizedSummary.step, requestedSummaryStepSeconds]
  )
  useEffect(() => {
    if (!topruSummaryQuery.isFetching && topruSummaryQuery.isFetched) {
      setDisplayedTrendTimeRangeValue(queryTimeRangeValue)
      setDisplayedSummaryStepSeconds(resolvedSummaryStepSeconds)
    }
  }, [
    queryTimeRangeValue,
    resolvedSummaryStepSeconds,
    topruSummaryQuery.isFetched,
    topruSummaryQuery.isFetching
  ])
  const totalSummaryRU = useMemo(
    () => summaryItems.reduce((sum, item) => sum + (item.total_ru || 0), 0),
    [summaryItems]
  )
  const realTrendSeries = useMemo(
    () =>
      summaryItems.map((item) => {
        const identity = resolveTopSQLIdentity(item.sql_text, item.sql_digest)

        return {
          key: getTopRURecordKey(item.sql_digest),
          label: identity.displayName,
          isOthers: identity.isOthers,
          points: fillTrendPointGaps(
            (item.timestamp_sec || []).map((timestamp, index) => ({
              timestamp,
              value: item.total_ru_by_time?.[index] ?? 0
            })),
            displayedSummaryStepSeconds,
            displayedTrendTimeRangeValue
          )
        }
      }),
    [displayedSummaryStepSeconds, displayedTrendTimeRangeValue, summaryItems]
  )
  const overviewRecords = useMemo(
    () =>
      summaryItems.map((item) => {
        const identity = resolveTopSQLIdentity(item.sql_text, item.sql_digest)
        const totalRU = item.total_ru || 0
        const executions = item.exec_count || 0
        const totalLatencyNs = item.duration_ns || 0

        return {
          key: getTopRURecordKey(item.sql_digest),
          trendKey: getTopRURecordKey(item.sql_digest),
          digest: identity.sqlDigest,
          sql: identity.displayName,
          isOthers: identity.isOthers,
          totalRU,
          meanRU: executions > 0 ? totalRU / executions : 0,
          share:
            totalSummaryRU > 0
              ? Number(((totalRU / totalSummaryRU) * 100).toFixed(2))
              : 0,
          executions,
          totalLatencyNs,
          meanLatencyNs: executions > 0 ? totalLatencyNs / executions : 0
        }
      }),
    [summaryItems, totalSummaryRU]
  )
  const tableRecords = useMemo(() => {
    return [...overviewRecords].sort((left, right) => {
      if (left.isOthers !== right.isOthers) {
        return left.isOthers ? 1 : -1
      }

      return right.totalRU - left.totalRU
    })
  }, [overviewRecords])
  const displayedTrendSeries = useMemo(() => {
    const seriesOrderMap = new Map(
      tableRecords.map((record, index) => [record.trendKey, index])
    )

    return [...realTrendSeries].sort(
      (left, right) =>
        (seriesOrderMap.get(left.key) ?? Number.MAX_SAFE_INTEGER) -
        (seriesOrderMap.get(right.key) ?? Number.MAX_SAFE_INTEGER)
    )
  }, [realTrendSeries, tableRecords])
  const visibleLoading =
    (topruSummaryQuery.isLoading && !topruSummaryQuery.data) ||
    ((view || 'overview') === 'users' &&
      topruUserStatsQuery.isLoading &&
      !topruUserStatsQuery.data)
  const visibleFetching =
    topruSummaryQuery.isFetching || topruUserStatsQuery.isFetching
  const analysisData = useMemo<
    TopSQLExecutionPlanAnalysisResponse | undefined
  >(() => {
    if (!analysisContext) {
      return undefined
    }

    const item = summaryItems.find(
      (summaryItem) =>
        getTopRURecordKey(summaryItem.sql_digest) === analysisContext.record.key
    )
    if (!item) {
      return undefined
    }

    const totalRU = item.total_ru || 0
    const executions = item.exec_count || 0
    const totalLatencyNs = item.duration_ns || 0
    const meanLatencyNs = executions > 0 ? totalLatencyNs / executions : 0
    const identity = resolveTopSQLIdentity(item.sql_text, item.sql_digest)
    const plans = buildTopSQLExecutionPlans({
      items: summaryPlanItems,
      recordKey: analysisContext.record.key,
      statementTotalRU: totalRU,
      stepSeconds: displayedSummaryStepSeconds,
      timeRangeValue: displayedTrendTimeRangeValue
    })

    return {
      statementTemplate: identity.sqlText,
      sqlDigest: identity.sqlDigest,
      isOthers: identity.isOthers,
      rank: analysisContext.rank,
      ru: totalRU,
      meanRU: executions > 0 ? totalRU / executions : 0,
      share:
        totalSummaryRU > 0
          ? Number(((totalRU / totalSummaryRU) * 100).toFixed(2))
          : 0,
      planCount: plans.length,
      executions,
      totalLatencyNs,
      meanLatencyNs,
      plans
    }
  }, [
    analysisContext,
    displayedSummaryStepSeconds,
    displayedTrendTimeRangeValue,
    summaryItems,
    summaryPlanItems,
    totalSummaryRU
  ])
  const analysisLoading =
    !!analysisContext && !analysisData && topruSummaryQuery.isLoading
  const analysisPlansLoading =
    !!analysisContext &&
    shouldFetchSummaryPlans &&
    topruSummaryPlanQuery.isLoading
  const analysisRecordIndex = useMemo(() => {
    if (!analysisContext) {
      return -1
    }

    return tableRecords.findIndex(
      (item) => item.key === analysisContext.record.key
    )
  }, [analysisContext, tableRecords])
  const handleOpenAnalysisRecord = (index: number) => {
    const nextRecord = tableRecords[index]
    if (!nextRecord) {
      return
    }

    setSelectedRecordKey(nextRecord.key)
    setAnalysisContext({ record: nextRecord, rank: index + 1 })
  }
  useEffect(() => {
    if (!tableRecords.length) {
      setSelectedRecordKey(undefined)
      return
    }

    const currentExists = tableRecords.some(
      (record) => record.key === selectedRecordKey
    )
    if (!currentExists) {
      setSelectedRecordKey(undefined)
    }
  }, [selectedRecordKey, tableRecords])

  const trendColorPalette = useMemo(
    () =>
      TOP_SQL_TREND_COLOR_ALPHAS.flatMap((alpha) =>
        TOP_SQL_TREND_COLOR_NAMES.map((colorName) =>
          withAlpha(colors[colorName][TOP_SQL_TREND_COLOR_SHADE], alpha)
        )
      ),
    [colors]
  )

  const seriesColorMap = useMemo(() => {
    return displayedTrendSeries.reduce<Record<string, string>>(
      (map, series, index) => {
        map[series.key] = trendColorPalette[index % trendColorPalette.length]
        return map
      },
      {}
    )
  }, [displayedTrendSeries, trendColorPalette])

  const trendSeries = useMemo(
    () =>
      displayedTrendSeries.map((series, index) => ({
        ...series,
        color:
          seriesColorMap[series.key] ||
          trendColorPalette[index % trendColorPalette.length]
      })),
    [displayedTrendSeries, seriesColorMap, trendColorPalette]
  )

  const handleTableHover = (trendKey: string) => {
    setHoveredKey(trendKey)
    onLegendItemOver(trendChartRef.current, trendKey)
  }

  const handleTableLeave = () => {
    setHoveredKey(undefined)
    onLegendItemOut(trendChartRef.current)
  }

  const handleBrushEnd: BrushEndListener = (event: BrushEvent) => {
    if (!event.x) {
      return
    }

    const brushRange = event.x.map((value) => Number(value) / 1000) as [
      number,
      number
    ]
    const delta = brushRange[1] - brushRange[0]
    const normalizedRange: [number, number] =
      delta < 60
        ? [
            Math.floor(brushRange[0] - (60 - delta) / 2),
            Math.ceil(brushRange[1] + (60 - delta) / 2)
          ]
        : [Math.floor(brushRange[0]), Math.ceil(brushRange[1])]

    const nextRange = normalizeTimeRangeValue(
      normalizedRange,
      topRuConfig.maxHistoryDays
    )

    eventTracking('Top RU Trend Brush Changed', {
      start: nextRange[0],
      end: nextRange[1]
    })
    setQueryTimeRangeValue(nextRange)
    setFilters(toURLTimeRange(fromTimeRangeValue(nextRange)))
    resetAutoRefreshCountdown()
  }

  const handleRefresh = () => {
    const nextTimeRangeValue = normalizeTimeRangeValue(
      toTimeRangeValue(timeRange),
      topRuConfig.maxHistoryDays
    )
    const isSameTimeWindow =
      nextTimeRangeValue[0] === queryTimeRangeValue[0] &&
      nextTimeRangeValue[1] === queryTimeRangeValue[1]

    if (isSameTimeWindow) {
      eventTracking('Top RU Refresh Button Clicked')
      topruSummaryQuery.refetch()
      topruUserStatsQuery.refetch()
      return
    }

    eventTracking('Top RU Refresh Button Clicked')
    setQueryTimeRangeValue(nextTimeRangeValue)
  }

  return (
    <>
      <Card withBorder p='lg'>
        <Stack gap='lg' data-testid='top-sql-page'>
          <Group gap='xs' wrap='nowrap' data-testid='top-sql-page-title'>
            <Title order={4}>Top RU</Title>
            <Badge
              variant='outline'
              color='gray'
              bg='gray.0'
              data-testid='top-sql-preview-badge'
            >
              Preview
            </Badge>
          </Group>

          <Alert color='peacock' data-testid='top-sql-info-banner'>
            <Typography variant='body-lg'>
              Shows SQLs consuming the most RU. Gradual rollout. If no data
              appears during workload, contact support for early access.
            </Typography>
          </Alert>

          <Flex
            justify='space-between'
            gap='md'
            wrap='wrap'
            data-testid='top-sql-toolbar'
          >
            <Group gap='md' wrap='wrap'>
              <SegmentedControl
                data-testid='top-sql-view-mode'
                value={view || 'overview'}
                onChange={(value) => {
                  eventTracking('Top RU View Mode Changed', { viewMode: value })
                  setFilters({
                    view: value as TopSQLViewMode,
                    user: value === 'users' ? user : undefined
                  })
                  resetAutoRefreshCountdown()
                }}
                data={[
                  { label: 'Overview', value: 'overview' },
                  { label: 'Sliced by Users', value: 'users' }
                ]}
              />

              {(view || 'overview') === 'users' && (
                <Select
                  data-testid='top-sql-user-select'
                  w={220}
                  placeholder='Select user'
                  value={selectedUser}
                  renderOption={renderUserOption}
                  disabled={visibleFetching || !userFilterOptions.length}
                  onChange={(value) => {
                    eventTracking('Top RU User Changed', { user: value ?? '' })
                    setFilters({ user: value ?? undefined })
                    resetAutoRefreshCountdown()
                  }}
                  data={userFilterOptions}
                  styles={{
                    input: {
                      fontStyle: isTopSQLSystemInternalUserValue(selectedUser)
                        ? 'italic'
                        : undefined
                    }
                  }}
                />
              )}

              <TimeRangePicker
                value={timeRange}
                onChange={(value) => {
                  const rawTimeRangeValue = toTimeRangeValue(value)
                  const normalizedTimeRangeValue = normalizeTimeRangeValue(
                    rawTimeRangeValue,
                    topRuConfig.maxHistoryDays
                  )

                  eventTracking('Top RU Time Range Change', {
                    timeRange: value
                  })
                  setQueryTimeRangeValue(normalizedTimeRangeValue)
                  setFilters(
                    isSameTimeRangeValue(
                      rawTimeRangeValue,
                      normalizedTimeRangeValue
                    )
                      ? toURLTimeRange(value)
                      : toURLTimeRange(
                          fromTimeRangeValue(normalizedTimeRangeValue)
                        )
                  )
                  resetAutoRefreshCountdown()
                }}
                quickRanges={QUICK_RANGES}
                minDateTime={() =>
                  dayjs()
                    .subtract(topRuConfig.maxHistoryDays, 'day')
                    .startOf('day')
                    .toDate()
                }
                maxDateTime={() => dayjs().toDate()}
                maxDuration={MAX_CUSTOM_RANGE_SECONDS}
                datePickerProps={{ allowSingleDateInRange: true }}
                loading={visibleFetching}
              />

              <Select
                data-testid='top-sql-top-select'
                w={108}
                value={normalizedTop}
                disabled={visibleFetching}
                onChange={(value) => {
                  const nextTop = normalizeTopLimit(
                    value || `${DEFAULT_TOP_LIMIT}`,
                    topRuConfig.maxTop
                  )

                  eventTracking('Top RU Limit Change', { top: nextTop })
                  setFilters({ top: nextTop })
                  resetAutoRefreshCountdown()
                }}
                data={limitOptions}
              />
            </Group>

            <AutoRefreshButton
              ref={autoRefreshRef}
              autoRefreshValue={autoRefreshValue}
              autoRefreshOptions={AUTO_REFRESH_OPTIONS}
              loading={visibleFetching}
              onAutoRefreshChange={(value) => {
                eventTracking('Top RU Auto Refresh Changed', {
                  autoRefreshValue: value
                })
                setAutoRefreshValue(value)
              }}
              onRefresh={handleRefresh}
            />
          </Flex>

          <Grid gutter='lg'>
            {(view || 'overview') !== 'users' && (
              <Grid.Col span={{ base: 12, lg: 4 }}>
                <UserShareCard
                  loading={
                    topruUserStatsQuery.isLoading && !topruUserStatsQuery.data
                  }
                  totalRU={userShareTotalRU}
                  items={userShareItems}
                />
              </Grid.Col>
            )}

            <Grid.Col
              span={{ base: 12, lg: (view || 'overview') === 'users' ? 12 : 8 }}
            >
              <Card withBorder p='md' h={280} data-testid='top-sql-trend-card'>
                <Stack gap='lg' h='100%'>
                  <Group justify='space-between' align='flex-start'>
                    <Typography variant='title-md'>
                      Real-Time RU Consumption Trend
                    </Typography>
                  </Group>

                  <Box
                    ref={trendChartSizeRef}
                    h='100%'
                    w='100%'
                    sx={{ flex: 1, minWidth: 0, minHeight: 0, display: 'flex' }}
                  >
                    <TrendChart
                      ref={trendChartRef}
                      data={trendSeries}
                      timeRangeValue={displayedTrendTimeRangeValue}
                      stepSeconds={displayedSummaryStepSeconds}
                      highlightedKey={hoveredKey}
                      onBrushEnd={handleBrushEnd}
                    />
                  </Box>
                </Stack>
              </Card>
            </Grid.Col>
          </Grid>

          <TopSQLTable
            data={tableRecords}
            loading={visibleLoading}
            selectedKey={selectedRecordKey}
            highlightedKey={hoveredKey}
            seriesColorMap={seriesColorMap}
            onSelect={setSelectedRecordKey}
            onHover={handleTableHover}
            onLeave={handleTableLeave}
            onRowClick={(record) => {
              const rank =
                tableRecords.findIndex((item) => item.key === record.key) + 1
              eventTracking('Top RU Row Clicked', {
                rank: rank || 1,
                sqlDigest: record.digest
              })
              setSelectedRecordKey(record.key)
              setAnalysisContext({ record, rank: rank || 1 })
            }}
          />
        </Stack>
      </Card>

      <SQLExecutionPlanDrawer
        opened={!!analysisContext}
        loading={analysisLoading}
        plansLoading={analysisPlansLoading}
        data={analysisData}
        timeRangeValue={displayedTrendTimeRangeValue}
        currentIndex={analysisRecordIndex}
        totalCount={tableRecords.length}
        onPrev={() => {
          eventTracking('Top RU Detail Previous SQL Clicked', {
            currentIndex: analysisRecordIndex + 1,
            totalCount: tableRecords.length
          })
          handleOpenAnalysisRecord(analysisRecordIndex - 1)
        }}
        onNext={() => {
          eventTracking('Top RU Detail Next SQL Clicked', {
            currentIndex: analysisRecordIndex + 1,
            totalCount: tableRecords.length
          })
          handleOpenAnalysisRecord(analysisRecordIndex + 1)
        }}
        onClose={() => setAnalysisContext(null)}
      />
    </>
  )
}

export default TopRUPageContent
