import { Alert, Badge, Card, Typography } from '@tidbcloud/uikit'
import { MRT_ColumnDef, ProTable } from '@tidbcloud/uikit/biz'
import { IconInfoCircle } from '@tidbcloud/uikit/icons'
import { capitalize } from 'lodash-es'
import React from 'react'

import { ContactUsLink } from 'dbaas/components/ContactUs/Link'
import dayjs from 'dbaas/components/dayjs'
import { HeroComponent } from 'dbaas/components/Measurement'
import { renderTimeColumn, defaultHeader } from 'dbaas/components/Table/utils'
import { useGetTenantCostQuota, useListStripeInvoices } from 'dbaas/services/billing'
import { FormsBillingConfig, FormsStripeInvoice } from 'dbaas/services/billing/interface'
import { defaultErrorMsg, getErrorMessage, UnexpectedError } from 'dbaas/services/errorCodes'

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

import { InvoiceActions } from './Actions'

export const renderMoneyColumn =
  (name: string, active?: boolean, isPoints?: boolean, isDecimal?: boolean) => (rowData: any) => {
    const num = Number(rowData[name])
    const amount = isPoints || isDecimal ? num : num / 100
    return <MoneyValue amount={amount} active={active} isPoints={isPoints} />
  }

export const Invoices: React.FC<
  React.PropsWithChildren<{
    hasDraftInvoice: boolean
    orgId: string
    billingConfig: FormsBillingConfig
  }>
> = ({ hasDraftInvoice, orgId, billingConfig }) => {
  const {
    data: invoices,
    isLoading: loading,
    error,
    isFetched
  } = useListStripeInvoices(orgId, billingConfig.billing_config_id)
  const { data: costQuota } = useGetTenantCostQuota(orgId, {
    query: {
      refetchInterval: false
    }
  })
  const errorMsg = error ? getErrorMessage(error) : ''

  const columns: MRT_ColumnDef<FormsStripeInvoice>[] = [
    {
      id: 'created',
      header: 'Month',
      accessorFn: (rowData) => renderTimeColumn('created', 'YYYY-MM')(rowData),
      maxSize: 120
    },
    {
      header: 'Invoice ID',
      accessorKey: 'number',
      minSize: 180
    },
    {
      id: 'due_date',
      header: 'Date Due',
      accessorFn: (rowData) => {
        if (rowData.due_date === '0') {
          return ''
        }
        return renderTimeColumn('due_date', 'YYYY-MM-DD')(rowData)
      },
      maxSize: 120
    },
    {
      id: 'invoice_status',
      header: 'Status',
      accessorFn: ({ status }: { status: string }) =>
        status ? (
          <Badge variant="dot" color={status === 'open' ? 'peacock' : 'green'} size="lg" sx={{ pointerEvents: 'none' }}>
            {capitalize(status)}
          </Badge>
        ) : (
          '-'
        ),
      minSize: 120,
      maxSize: 120
    },
    {
      id: 'total',
      header: 'Charge',
      accessorFn: renderMoneyColumn('total', false, false, true),
      mantineTableHeadCellProps: {
        align: 'right'
      },
      mantineTableBodyCellProps: {
        align: 'right'
      },
      maxSize: 150
    },
    {
      id: 'credit_used',
      header: 'Credits Used',
      accessorFn: renderMoneyColumn('credit_used', true, true, false),
      mantineTableHeadCellProps: {
        align: 'right'
      },
      mantineTableBodyCellProps: {
        align: 'right'
      },
      maxSize: 150
    },
    {
      id: 'amount_due',
      header: defaultHeader('amount_due'),
      accessorFn: renderMoneyColumn('amount_due', false, false, true),
      mantineTableHeadCellProps: {
        align: 'right'
      },
      mantineTableBodyCellProps: {
        align: 'right'
      },
      maxSize: 150
    },
    {
      id: 'amount_paid',
      header: 'Paid',
      accessorFn: renderMoneyColumn('amount_paid', false, false, true),
      mantineTableHeadCellProps: {
        align: 'right'
      },
      mantineTableBodyCellProps: {
        align: 'right'
      },
      maxSize: 150
    },
    {
      id: 'action',
      header: 'Action',
      size: 40,
      accessorFn: (row) => <InvoiceActions row={row} orgId={orgId} billingConfigId={billingConfig.billing_config_id} />,
      mantineTableHeadCellProps: {
        align: 'center'
      },
      mantineTableBodyCellProps: {
        align: 'center'
      }
    }
  ]

  return (
    <Card p={24}>
      {/*
        -1 means unlimited
      */}
      {costQuota && costQuota?.cost_quota_limit !== '-1' && (
        <Alert icon={<IconInfoCircle size={14} />} styles={{ icon: { marginRight: 8 }, root: { marginBottom: 16 } }}>
          <span>
            According to the{' '}
            <a href="https://docs.pingcap.com/tidbcloud/tidb-cloud-billing#invoices" target="_blank" rel="noreferrer">
              billing policy
            </a>
            , TiDB Cloud will generate an invoice once your cost reaches a quota (
            <b>
              <MoneyValue amount={costQuota.cost_quota_limit || ''} />
            </b>
            ). If you want to raise the quota or receive one invoice per month, please{' '}
            <ContactUsLink text="contact sales" help="Pricing" />.
          </span>
        </Alert>
      )}
      <ProTable
        columns={columns}
        data={invoices ?? []}
        emptyMessage="No Invoices"
        errorMessage={errorMsg === defaultErrorMsg ? UnexpectedError : errorMsg}
        loading={loading}
      />
      {hasDraftInvoice && (
        <Typography fz={12} c="carbon.7" mt={8}>
          * The billing of {dayjs().subtract(1, 'M').format('MMM YYYY')} is being processed, it will be completed before{' '}
          {dayjs().format('MMM')} 9, {dayjs().format('YYYY')}.
        </Typography>
      )}
      {isFetched && <HeroComponent />}
    </Card>
  )
}
