/* eslint-disable react/require-default-props */
import Empty from '@arcblock/ux/lib/Empty';
import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
import Toast from '@arcblock/ux/lib/Toast';
import { ConfirmDialog, api, formatError, formatTime, usePaymentContext } from '@blocklet/payment-react';
import type { TUsageRecord } from '@blocklet/payment-types';
import { Alert, Box, Button, CircularProgress, TextField, Typography } from '@mui/material';
import { useRequest } from 'ahooks';
import { useState } from 'react';
import { Bar, BarChart, Rectangle, Tooltip, XAxis, YAxis } from 'recharts';
import { withQuery } from 'ufo';

import { stringToColor } from '../../../libs/util';

// FIXME: pagination here
const fetchData = (
  subscriptionId: string,
  id: string,
  start: number = 0,
  end: number = 0
): Promise<{ list: TUsageRecord[]; count: number }> => {
  return api
    .get(
      withQuery(`/api/subscriptions/${subscriptionId}/usage-records`, {
        subscription_item_id: id,
        pageSize: 100,
        start,
        end,
      })
    )
    .then((res: any) => res.data);
};

const colors = {
  normal: stringToColor('normal'),
  active: stringToColor('active'),
};

function addUsageQuantity({
  subscriptionItemId,
  params,
}: {
  subscriptionItemId: string;
  params: import('stripe').Stripe.UsageRecordCreateParams;
}) {
  return api
    .post(`api/subscription-items/${subscriptionItemId}/add-usage-quantity`, params)
    .then((res: any) => res.data);
}

export function UsageRecordDialog({
  title,
  subscriptionId,
  id,
  onConfirm,
  start = 0,
  end = 0,
  disableAddUsageQuantity = false,
}: {
  title?: string;
  subscriptionId: string;
  id: string;
  onConfirm: any;
  start?: number;
  end?: number;
  disableAddUsageQuantity?: boolean;
}) {
  const { t } = useLocaleContext();
  const { loading, error, data } = useRequest(() => fetchData(subscriptionId, id, start, end), {
    refreshDeps: [subscriptionId, id, start, end],
  });
  const settings = usePaymentContext();
  const [usageQuantity, setUsageQuantity] = useState(1);

  if (error) {
    return (
      <ConfirmDialog
        title={title || t('admin.subscription.usage.current')}
        message={<Alert severity="error">{error.message}</Alert>}
        onConfirm={onConfirm}
        onCancel={onConfirm}
        color="primary"
        cancel={false}
      />
    );
  }

  if (loading || !data) {
    return (
      <ConfirmDialog
        title={title || t('admin.subscription.usage.current')}
        message={<CircularProgress />}
        onConfirm={onConfirm}
        onCancel={onConfirm}
        color="primary"
        cancel={false}
      />
    );
  }

  const handAddUsageQuantity = async () => {
    try {
      await addUsageQuantity({
        subscriptionItemId: id,
        params: {
          quantity: usageQuantity,
        },
      });
      Toast.success(t('admin.usageRecord.add.success'));
      onConfirm();
    } catch (err) {
      console.error(err);
      Toast.error(formatError(err));
    }
  };
  return (
    <ConfirmDialog
      title={title || t('admin.subscription.usage.current')}
      message={
        <>
          {start && end ? (
            <Typography
              variant="h6"
              sx={{
                mb: 2,
              }}>
              {t('admin.subscription.usage.cycle')}: {formatTime(start * 1000)} - {formatTime(end * 1000)}
            </Typography>
          ) : null}
          {data.list.length > 0 ? (
            <BarChart
              width={540}
              height={240}
              data={data.list.map((item) => ({
                ...item,
                date: new Date(item.timestamp * 1000).toLocaleString(),
              }))}
              margin={{
                top: 5,
                right: 5,
                left: 5,
                bottom: 5,
              }}>
              <Tooltip />
              <Bar
                dataKey="quantity"
                fill={colors.normal}
                activeBar={<Rectangle fill={colors.active} strokeWidth={0} />}
              />
              <XAxis dataKey="date" />
              <YAxis mirror />
            </BarChart>
          ) : (
            <Empty>{t('admin.usageRecord.empty')}</Empty>
          )}
          {!settings.livemode && window.location.pathname.includes('/admin/billing') && !disableAddUsageQuantity && (
            <Box
              sx={{
                pt: 1,
                pb: 1,
                gap: 1,
                display: 'flex',
                justifyContent: 'center',
                alignItems: 'center',
              }}>
              <TextField
                id="add-usage-record"
                label={t('admin.usageRecord.add.quantity')}
                type="number"
                size="small"
                value={usageQuantity}
                onChange={(e) => setUsageQuantity(+e.target.value)}
                slotProps={{
                  inputLabel: {
                    shrink: true,
                  },
                }}
              />
              <Button onClick={handAddUsageQuantity} sx={{ color: 'text.link' }}>
                {t('admin.usageRecord.add.label')}
              </Button>
            </Box>
          )}
        </>
      }
      onConfirm={onConfirm}
      onCancel={onConfirm}
      color="primary"
      cancel={false}
    />
  );
}

export default function UsageRecords({
  subscriptionId,
  id,
  start = 0,
  end = 0,
}: {
  subscriptionId: string;
  id: string;
  start?: number;
  end?: number;
}) {
  const { t } = useLocaleContext();
  const [open, setOpen] = useState(false);
  return (
    <Box>
      <Button size="small" variant="text" color="info" onClick={() => setOpen(true)}>
        {t('admin.subscription.usage.view')}
      </Button>
      {open && (
        <UsageRecordDialog
          subscriptionId={subscriptionId}
          id={id}
          start={start}
          end={end}
          onConfirm={() => setOpen(false)}
        />
      )}
    </Box>
  );
}
