import { Typography, useComputedColorScheme, useMantineTheme } from '@tidbcloud/uikit'
import {
  MRT_Cell,
  MRT_Column,
  MRT_ColumnDef,
  MRT_Row,
  MRT_TableInstance,
  ProTable,
  renderExpandCell
} from '@tidbcloud/uikit/biz'
import React from 'react'

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

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

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

interface ProTableCellProps<TData extends Record<string, any>> {
  cell: MRT_Cell<TData>
  renderedCellValue: number | string | React.ReactNode
  column: MRT_Column<TData>
  row: MRT_Row<TData>
  table: MRT_TableInstance<TData>
}

interface ServiceBillsTableProps {
  data: CostsItem[]
  loading: boolean
  error: string
  isCurrentMonth: boolean
  currentBill?: FormsMonthlycostExplorerResult
  withSorting?: boolean
  useCassandraServiceNames?: boolean
}

export const ServiceBillsTable: React.FC<ServiceBillsTableProps> = ({
  data,
  loading,
  error,
  isCurrentMonth,
  currentBill,
  withSorting = false,
  useCassandraServiceNames = false
}) => {
  const colorScheme = useComputedColorScheme()
  const isLight = colorScheme === 'light'
  const theme = useMantineTheme()

  const footerRenders = createFooterRenders(currentBill, isLight, theme)

  const renderCell = <T extends Record<string, any> = {}>({ cell, ...rest }: ProTableCellProps<T>) => {
    const value = cell.getValue()
    const Cell = renderExpandCell({ cell, ...rest })
    if (value === 'TiDB Cloud Starter') {
      return <StarterTips>{Cell}</StarterTips>
    }
    if (typeof value === 'string' && hasBasic(value)) {
      return (
        <BasicTips size={14} service={value as string}>
          {Cell}
        </BasicTips>
      )
    }
    return hasBeta(value) ? <BetaTips>{Cell}</BetaTips> : Cell
  }

  const columns: MRT_ColumnDef<CostsItem>[] = [
    {
      id: 'name',
      accessorFn: (row) => formatBillingServiceName(row.name, { useCassandraServiceNames }),
      header: 'Service Bills',
      footer: loading ? undefined : 'Total',
      Cell: renderCell,
      enableSorting: false,
      mantineTableHeadCellProps: {
        sx: {
          paddingLeft: '12px !important'
        }
      },
      mantineTableBodyCellProps: {
        sx: {
          paddingLeft: '12px !important'
        }
      },
      mantineTableFooterCellProps: {
        sx: {
          paddingLeft: '12px !important'
        }
      }
    },
    {
      header: 'Running Total',
      accessorFn: (row) => <MoneyValue monospaced amount={row.costs?.raw_price || '0'} />,
      Footer: loading ? undefined : footerRenders.runningTotal,
      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.costs?.raw_price) || 0) - (Number(rowB.original.costs?.raw_price) || 0)
      }
    },
    {
      header: 'Discounts',
      accessorFn: (row) => {
        return <MoneyValue monospaced amount={toNegative(row.costs?.discount_price || '0')} negativeZero />
      },
      Footer: loading ? undefined : footerRenders.discounts,
      mantineTableHeadCellProps: {
        align: 'right'
      },
      mantineTableBodyCellProps: {
        align: 'right'
      },
      enableSorting: false
    },
    {
      header: 'Credits',
      accessorFn: (row) => <MoneyValue monospaced amount={toNegative(row.credit?.cost_price || '0')} negativeZero />,
      Footer: loading ? undefined : footerRenders.credits,
      mantineTableHeadCellProps: {
        align: 'right'
      },
      mantineTableBodyCellProps: {
        align: 'right'
      },
      enableSorting: false
    },
    {
      header: 'Total Cost',
      accessorFn: (row) => <MoneyValue monospaced amount={row.bill?.cost_price || '0'} />,
      id: 'usage',
      size: 106,
      Footer: loading ? undefined : footerRenders.totalCost,
      mantineTableHeadCellProps: {
        align: 'right',
        sx: {
          paddingRight: '12px !important',
          ...(withSorting
            ? {
                '.mrt-table-head-cell-labels': {
                  flexDirection: 'row'
                }
              }
            : undefined)
        }
      },
      mantineTableBodyCellProps: {
        align: 'right',
        sx: {
          paddingRight: '12px !important'
        }
      },
      mantineTableFooterCellProps: {
        align: 'right',
        sx: {
          paddingRight: '12px !important'
        }
      },
      enableSorting: withSorting,
      sortingFn: (rowA, rowB) => {
        return (Number(rowA.original.bill?.cost_price) || 0) - (Number(rowB.original.bill?.cost_price) || 0)
      }
    }
  ]

  return (
    <>
      <ProTable
        data={data}
        columns={columns}
        loading={loading}
        enableSorting={withSorting}
        errorMessage={error}
        emptyMessage="No Data"
        enableExpanding
        mantinePaperProps={{ my: 8 }}
        mantineTableFooterProps={{ display: data.length ? undefined : 'none' }}
      />
      {isCurrentMonth && (
        <p>
          <Typography variant="body-lg">
            <strong>Note:</strong> Due to delays and other reasons, the billing details of the current month are for
            reference only. You cannot reconcile your account based on the data. The details of the final consumption
            for the present month are based on the data of the next month.
          </Typography>
        </p>
      )}
    </>
  )
}
