import { Box, Button, Card, CardProps, Flex, Typography } from '@tidbcloud/uikit'
import { DEFAULT_TIME_RANGE, LabelTooltip, toTimeRangeValue } from '@tidbcloud/uikit/biz'
import { observer } from 'mobx-react'
import { useCallback, useEffect, useState } from 'react'
import { useHistory } from 'react-router-dom'

import { getMetricData } from 'dbaas/components/ChartCard/helpers'
import { AccessDeniedHoverHint } from 'dbaas/contexts/access-control'
import { SharedTiDB } from 'dbaas/screens/NextGen/shared/model/shared-tidb-state'
import { useGetMetricsQueryRangeURL } from 'dbaas/services/useO11YQuery'
import useStores from 'dbaas/stores/useStores'
import { formatNumberAutoPrecision, formatStorage } from 'dbaas/utils/format'

interface StandardCapacityProps extends Omit<CardProps, 'children'> {
  tidb: SharedTiDB
}

const StorageMetricItem: React.FC<
  React.PropsWithChildren<{
    label: string
    value: number | string
    tooltip?: string
  }>
> = ({ label, value, tooltip }) => {
  return (
    <Box>
      <Flex align="center">
        <Typography variant="body-lg">
          {label}
          {tooltip && <LabelTooltip width={400} label={tooltip} />}
        </Typography>
      </Flex>
      <Typography fz={26} fw={400} lh="34px" c="carbon.9">
        {typeof value === 'number' ? formatStorage(value) : value}
      </Typography>
    </Box>
  )
}

export const StandardCapacity = observer(({ tidb, ...rootProps }: StandardCapacityProps) => {
  const {
    store: {
      tenantData: { id: orgId }
    }
  } = useStores()
  const times = toTimeRangeValue(DEFAULT_TIME_RANGE)
  const history = useHistory()
  const [rowData, setRowData] = useState([])
  const [columnData, setColumnData] = useState([])
  const intervalTime = 30 * 1000

  const {
    data: metricSourceURI,
    isLoading: isLoadingMetricsURL,
    metricRequestOptions
  } = useGetMetricsQueryRangeURL(orgId, tidb)

  const rowQuery =
    'quantile_over_time(0.5, sum(avg by(keyspace_id, region_id) (tikv_store_size_bytes{type="used"}))[5m]) or vector(0)'
  const columnQuery =
    'quantile_over_time(0.5, sum(avg by(keyspace_id, region_id) (tikv_store_size_bytes{type="tiflash_used"}))[5m]) or vector(0)'

  const getRowCapacityData = useCallback(async () => {
    try {
      const row = await getMetricData({
        sourceURI: metricSourceURI ?? '',
        startTime: times[0],
        endTime: times[1],
        timeStep: 30,
        promql: rowQuery,
        requestOptions: metricRequestOptions
      })
      const querys = row?.data?.data?.result ?? []
      setRowData(querys.length ? querys[0].values || [] : [])
    } finally {
      setTimeout(() => {
        getRowCapacityData()
      }, intervalTime)
    }
  }, [intervalTime, metricRequestOptions, metricSourceURI, rowQuery])

  const getColumnCapacityData = useCallback(async () => {
    try {
      const column = await getMetricData({
        sourceURI: metricSourceURI ?? '',
        startTime: times[0],
        endTime: times[1],
        timeStep: 30,
        promql: columnQuery,
        requestOptions: metricRequestOptions
      })
      const querys = column?.data?.data?.result ?? []
      querys.length && setColumnData(querys[0].values ?? [])
    } finally {
      setTimeout(() => {
        getColumnCapacityData()
      }, intervalTime)
    }
  }, [columnQuery, intervalTime, metricRequestOptions, metricSourceURI])

  useEffect(() => {
    if (!metricSourceURI || isLoadingMetricsURL) return
    getRowCapacityData()
    getColumnCapacityData()
  }, [metricSourceURI, isLoadingMetricsURL, getRowCapacityData, getColumnCapacityData])

  return (
    <Card p="xl" {...rootProps}>
      <Flex justify="space-between" align="center" mb={16}>
        <Typography variant="headline-sm">Capacity</Typography>
        <AccessDeniedHoverHint id="TidbxCapacityUpdate" scopeProps={{ tidbId: tidb.tidbId }}>
          {({ accessible }) => (
            <Button
              variant="default"
              size="compact-sm"
              disabled={!accessible}
              onClick={() => {
                history.push(`/tidbs/${tidb.tidbId}/edit-capacity`)
              }}
            >
              Update Capacity
            </Button>
          )}
        </AccessDeniedHoverHint>
      </Flex>

      <Flex>
        <Box w="50%">
          <Typography variant="body-lg">
            Provisioned Compute
            {/* <LabelTooltip width={400} label="// todo" /> */}
          </Typography>
          <Flex gap={32} mt={12}>
            <StorageMetricItem label="Minimum RCU" value={`${formatNumberAutoPrecision(tidb.minRcu ?? 0)}`} />
            <StorageMetricItem label="Maximum RCU" value={`${formatNumberAutoPrecision(tidb.maxRcu ?? 0)}`} />
          </Flex>
        </Box>

        <Box>
          <Typography variant="body-lg">
            Storage
            {/* <LabelTooltip width={400} label="// todo" /> */}
          </Typography>
          <Flex gap={32} mt={12}>
            <StorageMetricItem
              label="Row-based Storage"
              value={formatStorage(rowData.length ? Number(rowData[rowData.length - 1][1] / 1024 / 1024) : 0)}
              tooltip={`The "row-based storage" refers to the storage space that stores data in a row-based format.`}
            />
            <StorageMetricItem
              label="Columnar Storage"
              value={formatStorage(columnData.length ? Number(columnData[columnData.length - 1][1] / 1024 / 1024) : 0)}
              tooltip={`The "columnar storage" refers to the storage space that stores data in a column-based format.`}
            />
          </Flex>
        </Box>
      </Flex>
    </Card>
  )
})
