import React from 'react'

import {
  Box,
  Card,
  Flex,
  Progress,
  Skeleton,
  Stack,
  Typography,
  useMantineTheme
} from '@tidbcloud/uikit'

import { SQLWithPopover } from '~/pages/cluster/components/SQLWithPopover'
import { withAlpha } from '~/pages/cluster/top-ru/colors'

import type {
  StatementContributorItem,
  StatementMetricKey
} from './statementV2'
import { formatStatementMetricValue } from './statementV2'

type ContributorCardVariant = 'default' | 'sql'

interface ContributorCardProps {
  title: string
  total: number
  metric: StatementMetricKey
  totalValue: number
  items: StatementContributorItem[]
  loading?: boolean
  testId: string
  variant?: ContributorCardVariant
}

function renderLabel(
  item: StatementContributorItem,
  index: number,
  variant: ContributorCardVariant
) {
  if (variant === 'sql') {
    return (
      <Flex gap={8} align='flex-start' sx={{ flex: 1, minWidth: 0 }}>
        <Typography
          variant='body-lg'
          sx={{ flexShrink: 0, lineHeight: '24px' }}
        >
          {index + 1}.
        </Typography>
        <Box sx={{ flex: 1, minWidth: 0, height: 20 }}>
          {item.label ? (
            <SQLWithPopover sql={item.label} position='left' />
          ) : (
            <Typography c='dimmed' fs='italic'>
              Others
            </Typography>
          )}
        </Box>
      </Flex>
    )
  }

  return (
    <Typography
      variant='body-lg'
      sx={{
        flex: 1,
        minWidth: 0,
        overflow: 'hidden',
        textOverflow: 'ellipsis',
        whiteSpace: 'nowrap'
      }}
    >
      {index + 1}. {item.label}
    </Typography>
  )
}

export default function ContributorCard({
  title,
  total,
  metric,
  totalValue,
  items,
  loading = false,
  testId,
  variant = 'default'
}: ContributorCardProps) {
  const { colors } = useMantineTheme()
  const barColors = [
    withAlpha(colors.navy[7], 0.8),
    withAlpha(colors.navy[7], 0.6),
    withAlpha(colors.navy[7], 0.4)
  ]

  return (
    <Card withBorder p='md' h={220} data-testid={testId}>
      <Stack gap='md' h='100%'>
        <Stack gap={2}>
          <Typography variant='title-md'>{title}</Typography>
          <Typography variant='headline-md'>
            {total >= 1000 ? '999+' : total}
          </Typography>
        </Stack>

        {loading ? (
          <Stack gap='sm' sx={{ flex: 1 }}>
            <Skeleton h={16} w='80%' />
            <Skeleton h={16} w='100%' />
            <Skeleton h={16} w='72%' />
            <Skeleton h={16} w='100%' />
          </Stack>
        ) : items.length ? (
          <Box
            sx={{
              flex: 1,
              minHeight: 0,
              overflowY: 'auto',
              overflowX: 'hidden',
              paddingRight: 4
            }}
          >
            <Stack gap={8}>
              {items.map((item, index) => (
                <Stack key={item.key} gap={6}>
                  <Flex gap='sm' justify='space-between' align='flex-start'>
                    {renderLabel(item, index, variant)}
                    <Typography
                      variant='label-md'
                      c='carbon.7'
                      sx={{ flexShrink: 0 }}
                    >
                      {formatStatementMetricValue(metric, item.value)}
                    </Typography>
                  </Flex>
                  <Progress
                    value={totalValue > 0 ? (item.value / totalValue) * 100 : 0}
                    size={8}
                    color={barColors[index % barColors.length]}
                    styles={{ root: { backgroundColor: '#E7ECEE' } }}
                  />
                </Stack>
              ))}
            </Stack>
          </Box>
        ) : (
          <Box
            h='100%'
            sx={{
              display: 'flex',
              alignItems: 'center',
              justifyContent: 'center'
            }}
          >
            <Typography variant='body-lg' c='carbon.7'>
              No data available.
            </Typography>
          </Box>
        )}
      </Stack>
    </Card>
  )
}
