/* eslint-disable react/no-unstable-nested-components */
import { getDurableData } from '@arcblock/ux/lib/Datatable';
import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
import { api, formatTime, getCustomerAvatar, Table } from '@blocklet/payment-react';
import type { TCustomer } from '@blocklet/payment-types';
import { Avatar, CircularProgress, Stack, Typography } from '@mui/material';
import { useLocalStorageState } from 'ahooks';
import { useEffect, useState } from 'react';
import { Link } from 'react-router-dom';
import SafeDidAddress from '../../../../components/safe-did-address';

const fetchData = (params: Record<string, any> = {}): Promise<{ list: TCustomer[]; count: number }> => {
  const search = new URLSearchParams();
  Object.keys(params).forEach((key) => {
    let v = params[key];
    if (key === 'q') {
      v = Object.entries(v)
        .map((x) => x.join(':'))
        .join(' ');
    }
    search.set(key, String(v));
  });
  return api.get(`/api/customers?${search.toString()}`).then((res: any) => res.data);
};

type SearchProps = {
  active?: string;
  pageSize: number;
  page: number;
  q?: any;
  o?: string;
};
export default function CustomersList() {
  const listKey = 'customers';
  const persisted = getDurableData(listKey);

  const { t } = useLocaleContext();
  const [search, setSearch] = useLocalStorageState<SearchProps>(listKey, {
    defaultValue: {
      active: '',
      o: 'desc',
      pageSize: persisted.rowsPerPage || 20,
      page: persisted.page ? persisted.page + 1 : 1,
    },
  });

  const [data, setData] = useState({}) as any;

  const refresh = () =>
    fetchData(search).then((res: any) => {
      setData(res);
    });

  useEffect(() => {
    refresh();
  }, [search]);

  if (!data.list) {
    return <CircularProgress />;
  }

  const columns = [
    {
      label: t('admin.product.name.label'),
      name: 'name',
      options: {
        customBodyRenderLite: (_: string, index: number) => {
          const item = data.list[index] as TCustomer;
          return (
            <Link to={`/admin/customers/${item.id}`}>
              <Stack
                direction="row"
                spacing={1}
                sx={{
                  alignItems: 'center',
                }}>
                <Avatar
                  src={getCustomerAvatar(
                    item?.did,
                    item?.updated_at ? new Date(item.updated_at).toISOString() : '',
                    48
                  )}
                  variant="circular"
                  alt={item?.name}
                />
                <Typography sx={{ wordBreak: 'break-all' }}>{item.name}</Typography>
              </Stack>
            </Link>
          );
        },
      },
    },
    {
      label: t('common.did'),
      name: 'did',
      options: {
        customBodyRenderLite: (_: string, index: number) => {
          const item = data.list[index] as TCustomer;
          return (
            <Link to={`/admin/customers/${item.id}`}>
              <SafeDidAddress did={item.did} />
            </Link>
          );
        },
      },
    },
    {
      label: t('common.email'),
      name: 'email',
      options: {
        customBodyRenderLite: (_: string, index: number) => {
          const item = data.list[index] as TCustomer;
          return <Link to={`/admin/customers/${item.id}`}>{item.email}</Link>;
        },
      },
    },
    {
      label: t('admin.customer.phone'),
      name: 'phone',
      options: {
        customBodyRenderLite: (_: string, index: number) => {
          const item = data.list[index] as TCustomer;
          return <Link to={`/admin/customers/${item.id}`}>{item.phone}</Link>;
        },
      },
    },
    {
      label: t('common.createdAt'),
      name: 'created_at',
      options: {
        sort: true,
        customBodyRenderLite: (_: string, index: number) => {
          const item = data.list[index] as TCustomer;
          return <Link to={`/admin/customers/${item.id}`}>{formatTime(item.created_at)}</Link>;
        },
      },
    },
  ];

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

  return (
    <Table
      hasRowLink
      durable={`__${listKey}__`}
      durableKeys={['page', 'rowsPerPage', 'searchText']}
      data={data.list}
      columns={columns}
      options={{
        count: data.count,
        page: search!.page - 1,
        rowsPerPage: search!.pageSize,
        onColumnSortChange(_: any, order: any) {
          setSearch({
            ...search!,
            q: search!.q || {},
            o: order,
          });
        },
        onSearchChange: (text: string) => {
          if (text) {
            setSearch({
              ...search!,
              q: {
                'like-name': text,
                'like-email': text,
                'like-did': text,
                'like-metadata': text,
                'like-phone': text,
              },
              pageSize: 100,
              page: 1,
            });
          } else {
            setSearch({
              ...search!,
              pageSize: 100,
              page: 1,
              q: {},
            });
          }
        },
      }}
      loading={!data.list}
      onChange={onTableChange}
      emptyNodeText={t('empty.customers')}
    />
  );
}
