/* eslint-disable react/no-unstable-nested-components */
import { getDurableData } from '@arcblock/ux/lib/Datatable';
import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
import { Status, api, formatTime, Table } from '@blocklet/payment-react';
import type { TPricingTableExpanded } from '@blocklet/payment-types';
import { Alert, CircularProgress, ToggleButton, ToggleButtonGroup, Typography } from '@mui/material';
import { useLocalStorageState, useRequest } from 'ahooks';
import { useEffect } from 'react';
import { Link } from 'react-router-dom';
import { joinURL } from 'ufo';
import useBus from 'use-bus';

import Copyable from '../../../../components/copyable';
import PricingTableActions from '../../../../components/pricing-table/actions';
import { ProductsProvider } from '../../../../contexts/products';

const fetchData = (params: Record<string, any> = {}): Promise<{ list: TPricingTableExpanded[]; count: number }> => {
  const search = new URLSearchParams();
  Object.keys(params).forEach((key) => {
    search.set(key, String(params[key]));
  });
  return api.get(`/api/pricing-tables?${search.toString()}`).then((res: any) => res.data);
};

function PricingTables() {
  const listKey = 'pricing-tables';
  const { t } = useLocaleContext();

  const persisted = getDurableData(listKey);
  const [search, setSearch] = useLocalStorageState<{ active: string; pageSize: number; page: number }>(listKey, {
    defaultValue: {
      active: '',
      pageSize: persisted.rowsPerPage || 20,
      page: persisted.page ? persisted.page + 1 : 1,
    },
  });

  const { loading, error, data, refresh } = useRequest(() => fetchData(search));
  useEffect(() => {
    refresh();
  }, [search, refresh]);

  useBus('pricingTable.created', () => refresh(), []);

  if (error) {
    return <Alert severity="error">{error.message}</Alert>;
  }

  if (loading || !data) {
    return <CircularProgress />;
  }

  const columns = [
    {
      label: t('common.url'),
      name: 'id',
      options: {
        customBodyRenderLite: (_: string, index: number) => {
          const item = data.list[index] as TPricingTableExpanded;
          return (
            <Copyable
              text={joinURL(window.blocklet.appUrl, window.blocklet.prefix, `/checkout/pricing-table/${item.id}`)}>
              <Typography sx={{ color: 'text.primary', mr: 1 }}>{item.id}</Typography>
            </Copyable>
          );
        },
      },
    },
    {
      label: t('common.status'),
      name: 'active',
      options: {
        customBodyRenderLite: (_: string, index: number) => {
          const item = data.list[index] as TPricingTableExpanded;
          return (
            <Link to={`/admin/products/${item.id}`}>
              <Status label={item?.active ? 'Active' : 'Archived'} color={item?.active ? 'success' : 'default'} />
            </Link>
          );
        },
      },
    },
    {
      label: t('common.title'),
      name: 'name',
      options: {
        customBodyRenderLite: (_: string, index: number) => {
          const item = data.list[index] as TPricingTableExpanded;
          return <Link to={`/admin/products/${item.id}`}>{item.name}</Link>;
        },
      },
    },
    {
      label: t('common.createdAt'),
      name: 'created_at',
      options: {
        sort: true,
        customBodyRenderLite: (_: string, index: number) => {
          const item = data.list[index] as TPricingTableExpanded;
          return <Link to={`/admin/products/${item.id}`}>{formatTime(item.created_at)}</Link>;
        },
      },
    },
    {
      label: t('common.actions'),
      name: 'id',
      options: {
        sort: false,
        customBodyRenderLite: (_: string, index: number) => {
          const doc = data.list[index] as TPricingTableExpanded;
          return <PricingTableActions data={doc} onChange={refresh} />;
        },
      },
    },
  ];

  const onTableChange = ({ page, rowsPerPage }: any) => {
    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']}
      title={
        <div className="table-toolbar-left">
          <ToggleButtonGroup
            value={search!.active}
            onChange={(_, value) => {
              if (value !== null) {
                setSearch((x: any) => ({ ...x, active: value }));
              }
            }}
            exclusive>
            <ToggleButton value="">All</ToggleButton>
            <ToggleButton value="true">Active</ToggleButton>
            <ToggleButton value="false">Archived</ToggleButton>
          </ToggleButtonGroup>
        </div>
      }
      data={data.list}
      columns={columns}
      options={{
        count: data.count,
        page: search!.page - 1,
        rowsPerPage: search!.pageSize,
      }}
      loading={loading}
      onChange={onTableChange}
    />
  );
}

export default function WrappedPricingTables() {
  return (
    <ProductsProvider>
      <PricingTables />
    </ProductsProvider>
  );
}
