/* eslint-disable react/no-unstable-nested-components */
import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
import Toast from '@arcblock/ux/lib/Toast';
import { api, formatError, formatTime, usePaymentContext, Table } from '@blocklet/payment-react';
import type { TPricingTableExpanded, TProduct } from '@blocklet/payment-types';
import { ArrowBackOutlined } from '@mui/icons-material';
import { Alert, Box, Button, CircularProgress, Divider, Grid, Stack, Typography } from '@mui/material';
import { styled } from '@mui/system';
import { useRequest, useSetState } from 'ahooks';
import { Link, useNavigate } from 'react-router-dom';
import { joinURL } from 'ufo';

import Copyable from '../../../../components/copyable';
import EventList from '../../../../components/event/list';
import InfoCard from '../../../../components/info-card';
import InfoRow from '../../../../components/info-row';
import MetadataEditor from '../../../../components/metadata/editor';
import MetadataList from '../../../../components/metadata/list';
import PricingTableActions from '../../../../components/pricing-table/actions';
import PricingTablePreview from '../../../../components/pricing-table/preview';
import SectionHeader from '../../../../components/section/header';
import { formatProductPrice, goBackOrFallback } from '../../../../libs/util';
import InfoMetric from '../../../../components/info-metric';
import InfoRowGroup from '../../../../components/info-row-group';

const fetchData = (id: string): Promise<TPricingTableExpanded> => {
  return api.get(`/api/pricing-tables/${id}`).then((res: any) => res.data);
};

export default function PricingTableDetail(props: { id: string }) {
  const { t, locale } = useLocaleContext();
  const navigate = useNavigate();
  const { settings } = usePaymentContext();
  const [state, setState] = useSetState({
    adding: {
      price: false,
    },
    editing: {
      metadata: false,
      product: false,
    },
    loading: {
      metadata: false,
      price: false,
      product: false,
    },
  });

  const { loading, error, data, runAsync } = useRequest(() => fetchData(props.id));

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

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

  const createUpdater = (key: string) => async (updates: TProduct) => {
    try {
      setState((prev) => ({ loading: { ...prev.loading, [key]: true } }));
      await api.put(`/api/pricing-tables/${props.id}`, updates).then((res: any) => res.data);
      Toast.success(t('common.saved'));
      runAsync();
    } catch (err) {
      console.error(err);
      Toast.error(formatError(err));
    } finally {
      setState((prev) => ({ loading: { ...prev.loading, [key]: false } }));
    }
  };

  const onUpdateMetadata = createUpdater('metadata');
  const onChange = (action: string) => {
    if (action === 'remove') {
      navigate('/admin/products/pricing-tables');
    } else {
      runAsync();
    }
  };

  const handleEditMetadata = () => {
    setState((prev) => ({ editing: { ...prev.editing, metadata: true } }));
  };

  return (
    <Grid container spacing={4} sx={{ mb: 4 }}>
      <Grid size={12}>
        <Stack
          className="page-header"
          direction="row"
          sx={{
            justifyContent: 'space-between',
            alignItems: 'center',
          }}>
          <Stack
            direction="row"
            onClick={() => goBackOrFallback('/admin/products/pricing-tables')}
            sx={{
              alignItems: 'center',
              fontWeight: 'normal',
              cursor: 'pointer',
            }}>
            <ArrowBackOutlined fontSize="small" sx={{ mr: 0.5, color: 'text.secondary' }} />
            <Typography variant="h6" sx={{ color: 'text.secondary', fontWeight: 'normal' }}>
              {t('admin.pricingTables')}
            </Typography>
          </Stack>
          <PricingTableActions data={data} onChange={onChange} variant="normal" />
        </Stack>
        <Box
          sx={{
            mt: 4,
            mb: 3,
            display: 'flex',

            gap: {
              xs: 2,
              sm: 2,
              md: 5,
            },

            flexWrap: 'wrap',

            flexDirection: {
              xs: 'column',
              sm: 'column',
              md: 'row',
            },

            alignItems: {
              xs: 'flex-start',
              sm: 'flex-start',
              md: 'center',
            },
          }}>
          <Stack
            direction="row"
            sx={{
              justifyContent: 'space-between',
              alignItems: 'center',
              gap: 5,
            }}>
            <Stack
              direction="column"
              sx={{
                alignItems: 'flex-start',
              }}>
              <Typography variant="h1">{data.name}</Typography>
              <Copyable
                text={joinURL(window.blocklet.appUrl, window.blocklet.prefix, `/checkout/pricing-table/${data.id}`)}>
                <Typography
                  variant="h6"
                  sx={{
                    color: 'text.secondary',
                    mr: 1,
                    maxWidth: {
                      xs: 300,
                      md: '100%',
                    },
                    textOverflow: 'ellipsis',
                    overflow: 'hidden',
                    whiteSpace: 'nowrap',
                  }}>
                  {joinURL(window.blocklet.prefix, `/checkout/pricing-table/${data.id}`)}
                </Typography>
              </Copyable>
            </Stack>
          </Stack>
          <Stack
            className="section-body"
            sx={{
              justifyContent: 'flex-start',
              flexWrap: 'wrap',

              'hr.MuiDivider-root:last-child': {
                display: 'none',
              },

              flexDirection: {
                xs: 'column',
                sm: 'column',
                md: 'row',
              },

              alignItems: 'flex-start',

              gap: {
                xs: 1,
                sm: 1,
                md: 3,
              },
            }}>
            <InfoMetric label={t('common.id')} value={<Copyable text={props.id} style={{ marginLeft: 4 }} />} divider />
          </Stack>
        </Box>
        <Divider />
      </Grid>
      <Grid size={12}>
        <Stack
          sx={{
            flexDirection: {
              xs: 'column',
              lg: 'row',
            },
            gap: 4,
            '.payment-link-column-1': {
              minWidth: {
                xs: '100%',
                lg: '600px',
              },
            },
            '.payment-link-column-2': {
              width: {
                xs: '100%',
                md: '100%',
                lg: '320px',
              },
              maxWidth: {
                xs: '100%',
                md: '33%',
              },
            },
          }}>
          <Box
            className="payment-link-column-1"
            sx={{
              flex: 1,
            }}>
            <Div direction="column" spacing={3}>
              <Box className="section">
                <SectionHeader title={t('admin.products')} />
                <Box className="section-body">
                  <Table
                    className="link-products-table"
                    toolbar={false}
                    footer={false}
                    locale={locale}
                    data={data.items}
                    columns={[
                      {
                        label: t('common.title'),
                        name: 'product_id',
                        options: {
                          sort: false,
                          customBodyRenderLite: (_: any, index: number) => {
                            const item = data.items[index] as any;
                            const itemCurrency = data?.currency || settings.baseCurrency;
                            return (
                              <Link
                                to={`/admin/products/${item.product_id}?currency_id=${itemCurrency?.id}&price_id=${item.price.id}`}>
                                <InfoCard
                                  name={item.product.name}
                                  description={formatProductPrice(
                                    // @ts-ignore
                                    { ...item.product, prices: [item.price] },
                                    itemCurrency,
                                    locale
                                  )}
                                  logo={item.product.images[0]}
                                />
                              </Link>
                            );
                          },
                        },
                      },
                      // {
                      //   label: t('common.quantity'),
                      //   name: 'quantity',
                      // },
                    ]}
                    options={{
                      count: data.items.length,
                      page: 0,
                      rowsPerPage: 20,
                    }}
                    emptyNodeText={t('empty.products')}
                  />
                </Box>
              </Box>
              <Divider />
              <Box className="section">
                <SectionHeader title={t('admin.details')} />
                <InfoRowGroup
                  sx={{
                    display: 'grid',
                    gridTemplateColumns: {
                      xs: 'repeat(1, 1fr)',
                      xl: 'repeat(2, 1fr)',
                    },
                    '@container (min-width: 1000px)': {
                      gridTemplateColumns: 'repeat(2, 1fr)',
                    },
                    '.info-row-wrapper': {
                      gap: 1,
                      flexDirection: {
                        xs: 'column',
                        xl: 'row',
                      },
                      alignItems: {
                        xs: 'flex-start',
                        xl: 'center',
                      },
                      '@container (min-width: 1000px)': {
                        flexDirection: 'row',
                        alignItems: 'center',
                      },
                    },
                  }}>
                  <InfoRow label={t('common.createdAt')} value={formatTime(data.created_at)} />
                  <InfoRow label={t('common.updatedAt')} value={formatTime(data.updated_at)} />
                </InfoRowGroup>
              </Box>
              <Divider />
              <Box className="section">
                <SectionHeader title={t('common.preview')} />
                <Box className="section-body" sx={{ maxWidth: 1050 }}>
                  <PricingTablePreview id={data.id} />
                </Box>
              </Box>
              <Divider />
              <Box className="section">
                <SectionHeader title={t('admin.events.title')} />
                <Box className="section-body">
                  <EventList features={{ toolbar: false }} object_id={data.id} />
                </Box>
              </Box>
            </Div>
          </Box>
          <Box className="payment-link-column-2">
            <Box className="section">
              <SectionHeader title={t('common.metadata.label')}>
                <Button
                  variant="text"
                  color="inherit"
                  size="small"
                  sx={{ color: 'text.link' }}
                  disabled={state.editing.metadata}
                  onClick={handleEditMetadata}>
                  {t('common.edit')}
                </Button>
              </SectionHeader>
              <Box className="section-body">
                <MetadataList data={data.metadata} handleEditMetadata={handleEditMetadata} />
                {state.editing.metadata && (
                  <MetadataEditor
                    data={data}
                    loading={state.loading.metadata}
                    onSave={onUpdateMetadata}
                    onCancel={() => setState((prev) => ({ editing: { ...prev.editing, metadata: false } }))}
                  />
                )}
              </Box>
            </Box>
          </Box>
        </Stack>
      </Grid>
    </Grid>
  );
}

const Div = styled(Stack)``;
