import { Col, Row, message, Spin, Card, Typography } from 'antd'
import React, { useEffect, useState } from 'react'

import {
  getTop10QPSTenants,
  getTop10TiFlashStorageTenants,
  getTop10TiKVStorageTenants
} from '../../../apiClient/services/devops'
import { EntityTopTenant } from '../../../apiClient/services/devops/interface'
import { TopTenantTable } from '../TopTenants'

const { Text } = Typography

enum ResourceType {
  QPS = 'QPS',
  TiKVStorage = 'TiKV Storage',
  TiFlashStorage = 'TiFlash Storage'
}

export const ResourceDashboard: React.FC<
  React.PropsWithChildren<unknown>
> = () => {
  return (
    <>
      <Row gutter={[16, 16]}>
        <TopResourceTenants resourceType={ResourceType.QPS} />
        <TopResourceTenants resourceType={ResourceType.TiKVStorage} />
        <TopResourceTenants resourceType={ResourceType.TiFlashStorage} />
      </Row>
    </>
  )
}

export const TopResourceTenants: React.FC<
  React.PropsWithChildren<{ resourceType: ResourceType }>
> = ({ resourceType }) => {
  const [tenants, setTenants] = useState<EntityTopTenant[]>([])
  const [loading, setLoading] = useState(false)
  useEffect(() => {
    async function fetchInfo() {
      try {
        setLoading(true)
        let request = getTop10QPSTenants
        if (resourceType === ResourceType.TiKVStorage) {
          request = getTop10TiKVStorageTenants
        } else if (resourceType === ResourceType.TiFlashStorage) {
          request = getTop10TiFlashStorageTenants
        }
        await request()
          .then((resp) => {
            setTenants(resp.data?.items || [])
          })
          .catch((err) => {
            message.error({
              content: err.response?.data?.errmsg || 'Internal server error',
              key: 'overview'
            })
          })
      } finally {
        setLoading(false)
      }
    }

    fetchInfo()
  }, [resourceType])
  let renderData
  if (
    resourceType === ResourceType.TiKVStorage ||
    resourceType === ResourceType.TiFlashStorage
  ) {
    renderData = (_: any, record: EntityTopTenant) => {
      return bytesToSize(record.value || 0)
    }
  }
  return (
    <>
      <Col span={24}>
        <Card
          title={
            <>
              Top10 Tenants By <Text mark>{resourceType}</Text>
            </>
          }
        >
          {loading ? (
            <Spin></Spin>
          ) : (
            <TopTenantTable tenants={tenants} renderValue={renderData} />
          )}
        </Card>
      </Col>
    </>
  )
}

function bytesToSize(bytes: number): string {
  const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB']
  if (bytes === 0) return 'n/a'
  const i = Math.min(
    Math.floor(Math.log(bytes) / Math.log(1024)),
    sizes.length - 1
  )
  if (i === 0) return `${bytes} ${sizes[i]}`
  return `${(bytes / 1024 ** i).toFixed(1)} ${sizes[i]}`
}
