/* eslint-disable @typescript-eslint/indent */
/* eslint-disable react/require-default-props */
/* eslint-disable react/no-unused-prop-types */
/* eslint-disable @typescript-eslint/naming-convention */
/* eslint-disable no-nested-ternary */
/* eslint-disable react/no-unstable-nested-components */
import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
import type { Paginated, TCreditTransactionExpanded } from '@blocklet/payment-types';
import { Box, Typography, Stack, Link, Grid } from '@mui/material';
import { useRequest } from 'ahooks';
// eslint-disable-next-line import/no-extraneous-dependencies
import { useNavigate } from 'react-router-dom';
import React, { useCallback, useEffect, useRef, useState } from 'react';
import { joinURL } from 'ufo';
import { styled } from '@mui/system';
import DateRangePicker, { type DateRangeValue } from '../../components/date-range-picker';
// eslint-disable-next-line import/no-extraneous-dependencies

import { formatBNStr, formatToDate, getPrefix } from '../../libs/util';
import { usePaymentContext } from '../../contexts/payment';
import api from '../../libs/api';
import Table from '../../components/table';
import { createLink, handleNavigation } from '../../libs/navigation';

type Result = Paginated<TCreditTransactionExpanded>;

const fetchData = (params: Record<string, any> = {}): Promise<Result> => {
  const search = new URLSearchParams();
  Object.keys(params).forEach((key) => {
    if (params[key]) {
      search.set(key, String(params[key]));
    }
  });

  return api.get(`/api/credit-transactions?${search.toString()}`).then((res: any) => res.data);
};

type Props = {
  customer_id?: string;
  subscription_id?: string;
  credit_grant_id?: string;
  pageSize?: number;
  onTableDataChange?: Function;
  showAdminColumns?: boolean;
  showTimeFilter?: boolean;
  source?: string;
  mode?: 'dashboard' | 'portal';
};

const getGrantDetailLink = (grantId: string, inDashboard: boolean) => {
  let path = `/customer/credit-grant/${grantId}`;
  if (inDashboard) {
    path = `/admin/customers/${grantId}`;
  }

  return {
    link: createLink(path),
    connect: false,
  };
};

const TransactionsTable = React.memo((props: Props) => {
  const {
    pageSize,
    customer_id,
    subscription_id,
    credit_grant_id,
    onTableDataChange,
    showAdminColumns = false,
    showTimeFilter = false,
    source,
    mode = 'portal',
  } = props;
  const listKey = 'credit-transactions-table';
  const { t, locale } = useLocaleContext();
  const { session } = usePaymentContext();
  const isAdmin = ['owner', 'admin'].includes(session?.user?.role || '');
  const navigate = useNavigate();

  // 如果没有传入 customer_id，使用当前登录用户的 DID
  const effectiveCustomerId = customer_id || session?.user?.did;

  const [search, setSearch] = useState<{
    pageSize: number;
    page: number;
    start?: number;
    end?: number;
  }>({
    pageSize: pageSize || 10,
    page: 1,
  });

  const [filters, setFilters] = useState<DateRangeValue>({
    start: undefined,
    end: undefined,
  });

  const handleDateRangeChange = useCallback((newValue: DateRangeValue) => {
    setFilters(newValue);
    setSearch((prev) => ({
      ...prev,
      page: 1,
      start: newValue.start || undefined,
      end: newValue.end || undefined,
    }));
  }, []);

  const { loading, data = { list: [], count: 0 } } = useRequest(
    () =>
      fetchData({
        ...search,
        customer_id: effectiveCustomerId,
        subscription_id,
        credit_grant_id,
        source,
      }),
    {
      refreshDeps: [search, effectiveCustomerId, subscription_id, credit_grant_id, source],
    }
  );

  // 初始化时应用默认日期筛选
  useEffect(() => {
    if (showTimeFilter && !search.start && !search.end) {
      handleDateRangeChange(filters);
    }
  }, [showTimeFilter, handleDateRangeChange, search.start, search.end, filters]);

  const prevData = useRef(data);

  useEffect(() => {
    if (onTableDataChange) {
      onTableDataChange(data, prevData.current);
      prevData.current = data;
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [data]);

  const columns = [
    {
      label: t('common.creditAmount'),
      name: 'credit_amount',
      align: 'right',
      options: {
        customBodyRenderLite: (_: string, index: number) => {
          const transaction = data?.list[index] as TCreditTransactionExpanded;
          const unit = transaction.meter?.unit || transaction.paymentCurrency.symbol;
          return (
            <Typography>
              {formatBNStr(transaction.credit_amount, transaction.paymentCurrency.decimal)} {unit}
            </Typography>
          );
        },
      },
    },
    !credit_grant_id && {
      label: t('common.creditGrant'),
      name: 'credit_grant',
      options: {
        customBodyRenderLite: (_: string, index: number) => {
          const transaction = data?.list[index] as TCreditTransactionExpanded;
          return (
            <Stack
              direction="row"
              spacing={1}
              onClick={(e) => {
                const link = getGrantDetailLink(transaction.credit_grant_id, isAdmin && mode === 'dashboard');
                handleNavigation(e, link.link, navigate);
              }}
              sx={{
                alignItems: 'center',
              }}>
              <Typography variant="body2" sx={{ color: 'text.link', cursor: 'pointer' }}>
                {transaction.creditGrant.name || `Grant ${transaction.credit_grant_id.slice(-6)}`}
              </Typography>
            </Stack>
          );
        },
      },
    },
    {
      label: t('common.description'),
      name: 'subscription',
      options: {
        customBodyRenderLite: (_: string, index: number) => {
          const transaction = data?.list[index] as TCreditTransactionExpanded;
          return (
            <Typography variant="body2">{transaction.subscription?.description || transaction.description}</Typography>
          );
        },
      },
    },
    ...(showAdminColumns && isAdmin
      ? [
          {
            label: t('common.meterEvent'),
            name: 'meter_event',
            options: {
              customBodyRenderLite: (_: string, index: number) => {
                const transaction = data?.list[index] as TCreditTransactionExpanded;
                if (!transaction.meter) {
                  return <Typography variant="body2">-</Typography>;
                }
                return (
                  <Link href={joinURL(getPrefix(), `/admin/billing/${transaction.meter.id}`)}>
                    <Typography variant="body2" sx={{ color: 'text.link' }}>
                      {transaction.meter.event_name}
                    </Typography>
                  </Link>
                );
              },
            },
          },
        ]
      : []),
    {
      label: t('admin.creditTransactions.transactionDate'),
      name: 'created_at',
      options: {
        customBodyRenderLite: (_: string, index: number) => {
          const transaction = data?.list[index] as TCreditTransactionExpanded;
          return (
            <Typography variant="body2">
              {formatToDate(transaction.created_at, locale, 'YYYY-MM-DD HH:mm:ss')}
            </Typography>
          );
        },
      },
    },
  ].filter(Boolean);

  const onTableChange = ({ page, rowsPerPage }: any) => {
    if (search.pageSize !== rowsPerPage) {
      setSearch((x) => ({ ...x, pageSize: rowsPerPage, page: 1 }));
    } else if (search.page !== page + 1) {
      setSearch((x) => ({ ...x, page: page + 1 }));
    }
  };

  return (
    <TableRoot>
      {showTimeFilter && (
        <Box sx={{ my: 2 }}>
          <Box sx={{ mt: 2 }}>
            <Grid
              container
              spacing={2}
              sx={{
                alignItems: 'center',
              }}>
              <Grid
                size={{
                  xs: 12,
                  sm: 6,
                  md: 4,
                }}>
                <DateRangePicker value={filters} onChange={handleDateRangeChange} size="small" fullWidth />
              </Grid>
            </Grid>
          </Box>
        </Box>
      )}
      <Table
        hasRowLink
        durable={`__${listKey}__`}
        durableKeys={['page', 'rowsPerPage']}
        data={data.list}
        columns={columns}
        options={{
          count: data.count,
          page: search.page - 1,
          rowsPerPage: search.pageSize,
        }}
        loading={loading}
        onChange={onTableChange}
        toolbar={false}
        sx={{ mt: 2 }}
        showMobile={false}
        mobileTDFlexDirection="row"
        emptyNodeText={t('admin.creditTransactions.noTransactions')}
      />
    </TableRoot>
  );
});

const TableRoot = styled(Box)`
  @media (max-width: ${({ theme }) => theme.breakpoints.values.md}px) {
    .MuiTable-root > .MuiTableBody-root > .MuiTableRow-root > td.MuiTableCell-root {
      > div {
        width: fit-content;
        flex: inherit;
        font-size: 14px;
      }
    }
    .invoice-summary {
      padding-right: 20px;
    }
  }
`;
export default function CreditTransactionsList(rawProps: Props) {
  const props = Object.assign(
    {
      customer_id: '',
      subscription_id: '',
      credit_grant_id: '',
      source: '',
      pageSize: 10,
      onTableDataChange: () => {},
      showAdminColumns: false,
      showTimeFilter: false,
      mode: 'portal',
    },
    rawProps
  );
  return <TransactionsTable {...props} />;
}
