import { Flex } from '@tidbcloud/uikit'
import { MRT_ColumnDef, ProTable, ProTableOptions } from '@tidbcloud/uikit/biz'
import React from 'react'

import { FormsUsageDetails } from 'dbaas/services/billing/interface'

import { TimezoneTips } from '../components/HeadLabel'
import { MoneyValue } from '../components/MoneyValue'

import { toNegative, hasBasic, hasBeta, BetaTips, BasicTips } from './helpers'
import { formatBillingServiceName } from './service-name'

interface UsageDetailsTableProps {
  data: FormsUsageDetails[]
  loading: boolean
  error: string
  tableProps?: Omit<ProTableOptions<FormsUsageDetails>, 'columns' | 'data' | 'loading'>
  columnNames?: {
    cluster?: string
  }
  withSorting?: boolean
  useCassandraServiceNames?: boolean
}

export const UsageDetailsTable: React.FC<UsageDetailsTableProps> = ({
  data,
  loading,
  error,
  tableProps,
  columnNames = {},
  withSorting = false,
  useCassandraServiceNames = false
}) => {
  const usageDetailColumns: MRT_ColumnDef<FormsUsageDetails>[] = [
    {
      header: 'Billed Date',
      Header: () => (
        <Flex align="center" gap={4}>
          Billed Date <TimezoneTips />
        </Flex>
      ),
      accessorKey: 'billed_date',
      mantineTableHeadCellProps: {
        sx: {
          paddingLeft: '12px !important'
        }
      },
      mantineTableBodyCellProps: {
        sx: {
          paddingLeft: '12px !important'
        }
      },
      enableSorting: false
    },
    {
      header: 'Project Name',
      accessorKey: 'project_name',
      enableSorting: false
    },
    {
      header: columnNames.cluster || 'Cluster Name',
      accessorKey: 'cluster_name',
      enableSorting: false
    },
    {
      header: 'Service',
      accessorKey: 'service',
      accessorFn(originalRow) {
        const service = formatBillingServiceName(originalRow.service, { useCassandraServiceNames })

        if (hasBasic(service)) {
          return (
            <BasicTips size={14} align={'flex-start'} sx={{ svg: { flexShrink: 0, marginTop: 4 } }} service={service}>
              <span>{service}</span>
            </BasicTips>
          )
        }
        if (hasBeta(service)) {
          return (
            <BetaTips size={14} align={'flex-start'} sx={{ svg: { flexShrink: 0, marginTop: 4 } }}>
              <span>{service}</span>
            </BetaTips>
          )
        }
        return service
      },
      enableSorting: false
    },
    {
      header: 'Running Total',
      accessorFn: (row) => {
        const num = row.amount === '0' ? '0' : row.amount
        return <MoneyValue monospaced amount={num || '0'} />
      },
      mantineTableHeadCellProps: {
        align: 'right',
        sx: withSorting
          ? {
              '.mrt-table-head-cell-labels': {
                flexDirection: 'row'
              }
            }
          : undefined
      },
      mantineTableBodyCellProps: {
        align: 'right'
      },
      enableSorting: withSorting,
      sortingFn: (rowA, rowB) => {
        return (Number(rowA.original.amount) || 0) - (Number(rowB.original.amount) || 0)
      }
    },
    {
      header: 'Discounts',
      id: 'discounts',
      accessorFn: (row) => {
        const num = row.discount_cost === '0' ? '0' : row.discount_cost
        return <MoneyValue monospaced amount={toNegative(num || '0')} negativeZero />
      },
      mantineTableHeadCellProps: {
        align: 'right'
      },
      mantineTableBodyCellProps: {
        align: 'right'
      },
      enableSorting: false,
      sortingFn: (rowA, rowB) => {
        return (Number(rowA.original.discount_cost) || 0) - (Number(rowB.original.discount_cost) || 0)
      }
    },
    {
      header: 'Credits',
      accessorFn: (row) => {
        const num = row.credit_usage === '0' ? '0' : row.credit_usage
        return <MoneyValue monospaced amount={toNegative(num || '0')} negativeZero />
      },
      mantineTableHeadCellProps: {
        align: 'right'
      },
      mantineTableBodyCellProps: {
        align: 'right'
      },
      sortingFn: (rowA, rowB) => {
        return (Number(rowA.original.credit_usage) || 0) - (Number(rowB.original.credit_usage) || 0)
      },
      enableSorting: false
    },
    {
      header: 'Total Cost',
      accessorKey: 'billable_cost',
      accessorFn: (row) => {
        const num = row.billable_cost === '0' ? '0' : row.billable_cost
        return <MoneyValue monospaced amount={num || '0'} />
      },
      mantineTableHeadCellProps: {
        align: 'right',
        sx: {
          paddingRight: '12px !important',
          ...(withSorting
            ? {
                '.mrt-table-head-cell-labels': {
                  flexDirection: 'row'
                }
              }
            : undefined)
        }
      },
      mantineTableBodyCellProps: {
        align: 'right',
        sx: {
          paddingRight: '12px !important'
        }
      },
      enableSorting: withSorting,
      sortingFn: (rowA, rowB) => {
        return (Number(rowA.original.billable_cost) || 0) - (Number(rowB.original.billable_cost) || 0)
      }
    }
  ]

  return (
    <ProTable
      columns={usageDetailColumns}
      enableStickyHeader
      enableColumnPinning
      loading={loading}
      enableSorting={withSorting}
      errorMessage={error}
      emptyMessage="No Data"
      data={data}
      initialState={{ columnPinning: { right: ['billable_cost'] } }}
      mantineTableHeadProps={{ opacity: 1 }}
      mantineTableContainerProps={{ sx: { maxHeight: '400px' } }}
      mantineTableBodyCellProps={{ h: 'auto' }}
      enableRowVirtualization
      rowVirtualizerOptions={{
        overscan: 20
      }}
      {...tableProps}
    />
  )
}
