/* 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, TCreditGrantExpanded } from '@blocklet/payment-types';
import { Box, Typography, Chip } from '@mui/material';
import { useRequest } from 'ahooks';
import React, { useEffect, useRef, useState } from 'react';
// eslint-disable-next-line import/no-extraneous-dependencies
import { useNavigate } from 'react-router-dom';

import { styled } from '@mui/system';
import { formatToDate, formatCreditAmount, formatBNStr } 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<TCreditGrantExpanded>;

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-grants?${search.toString()}`).then((res: any) => res.data);
};

type Props = {
  customer_id?: string;
  subscription_id?: string;
  status?: string;
  pageSize?: number;
  onTableDataChange?: Function;
  mode?: 'dashboard' | 'portal';
};

export function StatusChip({ status, label }: { status: string; label?: string }) {
  const getStatusColor = (statusValue: string) => {
    switch (statusValue) {
      case 'granted':
        return 'success';
      case 'pending':
        return 'warning';
      case 'expired':
        return 'default';
      case 'depleted':
        return 'default';
      case 'voided':
        return 'default';
      default:
        return 'default';
    }
  };

  return <Chip label={label || status} size="small" color={getStatusColor(status) as any} />;
}

const getLink = (grant: TCreditGrantExpanded, inDashboard: boolean) => {
  let path = `/customer/credit-grant/${grant.id}`;
  if (inDashboard) {
    path = `/admin/customers/${grant.id}`;
  }

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

const GrantsTable = React.memo((props: Props) => {
  const { pageSize, status = '', customer_id, subscription_id, onTableDataChange } = props;
  const listKey = 'credit-grants-table';
  const { t, locale } = useLocaleContext();
  const { session } = usePaymentContext();
  const navigate = useNavigate();

  const isAdmin = ['owner', 'admin'].includes(session?.user?.role || '');

  const inDashboard = props.mode === 'dashboard' && isAdmin;

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

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

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

  const prevData = useRef(data);

  const handleLinkClick = (e: React.MouseEvent, grant: TCreditGrantExpanded) => {
    const { link } = getLink(grant, inDashboard);
    handleNavigation(e, link, navigate, { target: link.external ? '_blank' : '_self' });
  };

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

  const columns = [
    {
      label: t('common.name'),
      name: 'name',
      options: {
        customBodyRenderLite: (_: string, index: number) => {
          const grant = data?.list[index] as TCreditGrantExpanded;
          return <Box onClick={(e) => handleLinkClick(e, grant)}>{grant.name || grant.id}</Box>;
        },
      },
    },
    {
      label: t('common.status'),
      name: 'status',
      options: {
        customBodyRenderLite: (_: string, index: number) => {
          const grant = data?.list[index] as TCreditGrantExpanded;
          return (
            <Box onClick={(e) => handleLinkClick(e, grant)}>
              <StatusChip status={grant.status} label={t(`admin.customer.creditGrants.status.${grant.status}`)} />
            </Box>
          );
        },
      },
    },
    {
      label: t('common.remainingCredit'),
      name: 'remaining_amount',
      align: 'right',
      options: {
        customBodyRenderLite: (_: string, index: number) => {
          const grant = data?.list[index] as TCreditGrantExpanded;
          return (
            <Box onClick={(e) => handleLinkClick(e, grant)}>
              <Typography variant="body2">
                {formatCreditAmount(
                  formatBNStr(grant.remaining_amount, grant.paymentCurrency.decimal),
                  grant.paymentCurrency.symbol
                )}
              </Typography>
            </Box>
          );
        },
      },
    },
    {
      label: t('common.scope'),
      name: 'scope',
      options: {
        customBodyRenderLite: (_: string, index: number) => {
          const grant = data?.list[index] as TCreditGrantExpanded;
          let scope = 'general';
          if (grant.applicability_config?.scope?.prices) {
            scope = 'specific';
          }
          return (
            <Box onClick={(e) => handleLinkClick(e, grant)}>
              {scope === 'specific' ? t('common.specific') : t('common.general')}
            </Box>
          );
        },
      },
    },
    {
      label: t('common.effectiveDate'),
      name: 'effective_at',
      options: {
        customBodyRenderLite: (_: string, index: number) => {
          const grant = data?.list[index] as TCreditGrantExpanded;
          const effectiveAt = grant.effective_at ? grant.effective_at * 1000 : grant.created_at;
          return (
            <Box onClick={(e) => handleLinkClick(e, grant)}>
              {formatToDate(effectiveAt, locale, 'YYYY-MM-DD HH:mm')}
            </Box>
          );
        },
      },
    },
    {
      label: t('common.expirationDate'),
      name: 'expires_at',
      options: {
        customBodyRenderLite: (_: string, index: number) => {
          const grant = data?.list[index] as TCreditGrantExpanded;
          return (
            <Box onClick={(e) => handleLinkClick(e, grant)}>
              <Typography variant="body2">
                {grant.expires_at ? formatToDate(grant.expires_at * 1000, locale, 'YYYY-MM-DD HH:mm') : '-'}
              </Typography>
            </Box>
          );
        },
      },
    },
  ];

  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>
      <Table
        hasRowLink
        durable={`__${listKey}__`}
        durableKeys={['page', 'rowsPerPage', 'searchText']}
        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.creditGrants.noGrants')}
      />
    </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 CreditGrantsList(rawProps: Props) {
  const props = Object.assign(
    {
      customer_id: '',
      subscription_id: '',
      status: 'granted,pending,depleted,expired',
      pageSize: 10,
      onTableDataChange: () => {},
    },
    rawProps
  );
  return <GrantsTable {...props} />;
}
