/* eslint-disable react/no-unstable-nested-components */
import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
import Empty from '@arcblock/ux/lib/Empty';
import { api, formatPrice, getSubscriptionTimeSummary, useMobile } from '@blocklet/payment-react';
import type { TSubscriptionExpanded } from '@blocklet/payment-types';
import {
  Avatar,
  AvatarGroup,
  Box,
  Button,
  CircularProgress,
  Divider,
  Stack,
  StackProps,
  Typography,
} from '@mui/material';
import { useInfiniteScroll } from 'ahooks';

import { useRef } from 'react';
import SubscriptionDescription from '../description';
import SubscriptionActions from './actions';
import SubscriptionStatus from '../status';
import useDelayedLoading from '../../../hooks/loading';
import { formatProxyUrl, isWillCanceled } from '../../../libs/util';

type SubscriptionListResponse = {
  count: number;
  list: TSubscriptionExpanded[];
  paging: { page: number; pageSize: number };
  totalCount: number;
};

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

const TAG_COUNT = 2;

type Props = {
  id: string;
  status: string;
  onChange?: (action?: string) => any | Promise<any>;
  onClickSubscription: (subscription: TSubscriptionExpanded) => void | Promise<void>;
  onlyActive?: boolean;
  changeActive?: (active: boolean) => void;
  setStatusState?: (state: boolean) => void;
  setHasSubscriptions?: (state: boolean) => void;
} & Omit<StackProps, 'onChange'>;

export default function CurrentSubscriptions({
  id,
  status,
  onChange = () => {},
  onClickSubscription,
  onlyActive = false,
  changeActive = () => {},
  setStatusState = () => {},
  setHasSubscriptions = () => {},
  ...rest
}: Props) {
  const { t, locale } = useLocaleContext();
  const { isMobile } = useMobile();
  const listRef = useRef<HTMLDivElement | null>(null);
  const pageSize = isMobile ? 5 : 10;

  const { data, loadMore, loadingMore, loading, reload } = useInfiniteScroll<SubscriptionListResponse>(
    (d) => {
      const page = d ? Math.ceil(d.list.length / pageSize) + 1 : 1;
      return fetchData({ page, pageSize, status, customer_id: id, activeFirst: true, showTotalCount: true });
    },
    {
      reloadDeps: [id, status],
      onSuccess(res) {
        if (res.totalCount > 0 || res.count > 0) {
          setStatusState?.(true);
          setHasSubscriptions?.(true);
        } else {
          setHasSubscriptions?.(false);
        }
      },
      ...(isMobile
        ? {}
        : {
            target: listRef,
            isNoMore: (d) => {
              return d?.list?.length === 0 || (d?.list?.length ?? 0) >= (d?.count ?? 0);
            },
          }),
    }
  );

  const showLoadingMore = useDelayedLoading(loadingMore);

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

  const hasAnySubscriptions = data.totalCount > 0;

  const hasMore = data && data.list?.length < data.count;
  const size = isMobile ? { width: 42, height: 42 } : { width: 44, height: 44 };
  return (
    <Stack direction="column" spacing={2} sx={{ mt: 2, containerType: 'inline-size' }}>
      {data.list?.length > 0 ? (
        <>
          <Stack
            ref={listRef}
            sx={{
              maxHeight: {
                xs: '100%',
                md: '700px',
              },
              overflowY: 'auto',
              webkitOverflowScrolling: 'touch',
              display: 'grid',
              gridTemplateColumns: {
                xs: 'repeat(1, 1fr)',
                md: 'repeat(2, 1fr)',
              },
              '@container (max-width: 600px)': {
                gridTemplateColumns: 'repeat(1, 1fr)',
              },
              gap: 2,
            }}>
            {data.list.map((subscription) => {
              const summary = getSubscriptionTimeSummary(subscription, locale);
              const subscriptionTime = summary
                ? t(`admin.subscription.${summary?.action}`, {
                    date: summary?.time,
                    prefix: summary?.isToday ? 'at' : 'on',
                  })
                : '';
              return (
                <Stack
                  key={subscription.id}
                  sx={{
                    flexWrap: 'wrap',
                    padding: 2,
                    borderRadius: 1,
                    border: '1px solid',
                    borderColor: 'divider',
                    boxShadow: 1,
                    display: 'flex',
                    flexDirection: 'column',
                    justifyContent: 'space-between',
                    gap: 2,
                    width: '100%',

                    '&:hover': {
                      backgroundColor: 'grey.50',
                      transition: 'background-color 200ms linear',
                      cursor: 'pointer',
                    },
                  }}>
                  <Stack
                    direction="column"
                    spacing={2}
                    {...rest}
                    sx={[
                      {
                        flex: 1,
                        width: '100%',
                      },
                      ...(Array.isArray(rest.sx) ? rest.sx : [rest.sx]),
                    ]}>
                    <Stack
                      direction="row"
                      spacing={1}
                      onClick={() => onClickSubscription(subscription)}
                      sx={{
                        alignItems: 'flex-start',
                        justifyContent: 'space-between',
                        width: '100%',
                      }}>
                      <Stack
                        direction="row"
                        spacing={1.5}
                        sx={{
                          alignItems: 'center',
                          width: '100%',
                        }}>
                        {subscription.metadata?.appLogo ? (
                          <Avatar
                            src={formatProxyUrl(subscription.metadata?.appLogo)}
                            alt={subscription.metadata?.appName}
                            variant="rounded"
                            sx={size}
                          />
                        ) : (
                          <AvatarGroup
                            max={2}
                            sx={{
                              '& .MuiAvatar-colorDefault': {
                                ...size,
                                boxSizing: 'border-box',
                              },
                            }}>
                            {subscription.items.slice(0, 2).map((item) =>
                              item.price.product.images.length > 0 ? (
                                // @ts-ignore
                                <Avatar
                                  key={item.price.product_id}
                                  src={item.price.product.images[0]}
                                  alt={item.price.product.name}
                                  variant="rounded"
                                  sx={size}
                                />
                              ) : (
                                <Avatar key={item.price.product_id} variant="rounded" sx={size}>
                                  {item.price.product.name.slice(0, 1)}
                                </Avatar>
                              )
                            )}
                          </AvatarGroup>
                        )}

                        <Stack
                          direction="column"
                          spacing={0.25}
                          sx={{
                            width: '100%',
                          }}>
                          <SubscriptionDescription
                            subscription={subscription}
                            hideSubscription
                            maxLength={isMobile ? 30 : 40}
                            variant={isMobile ? 'subtitle2' : 'subtitle1'}
                          />
                          <Box
                            sx={{
                              display: 'flex',
                              alignItems: 'center',
                              gap: 1,
                              justifyContent: 'space-between',
                            }}>
                            <SubscriptionStatus
                              subscription={subscription}
                              sx={{ height: 18, width: 'fit-content' }}
                              size="small"
                            />
                            {/* Vendor 信息显示 */}
                            {(() => {
                              const vendorConfig = subscription.items?.[0]?.price?.product?.vendor_config;
                              if (!vendorConfig || vendorConfig.length === 0) return null;

                              return (
                                <Box
                                  sx={{
                                    display: 'flex',
                                    alignItems: 'center',
                                    gap: 0.5,
                                    flexWrap: 'wrap',
                                  }}>
                                  {vendorConfig.slice(0, TAG_COUNT).map((vendor, index) => (
                                    <Box
                                      key={vendor.vendor_id || index}
                                      sx={{
                                        display: 'flex',
                                        alignItems: 'center',
                                        gap: 0.25,
                                        px: 0.5,
                                        py: 0.25,
                                        bgcolor: 'action.hover',
                                        borderRadius: 0.5,
                                        border: '1px solid',
                                        borderColor: 'divider',
                                      }}>
                                      <Box
                                        sx={{
                                          width: 4,
                                          height: 4,
                                          borderRadius: '50%',
                                          bgcolor: 'success.main',
                                        }}
                                      />
                                      <Typography
                                        variant="caption"
                                        sx={{
                                          color: 'text.secondary',
                                          fontSize: '0.7rem',
                                          fontWeight: 500,
                                          whiteSpace: 'nowrap',
                                        }}>
                                        {vendor.name || vendor.vendor_key}
                                      </Typography>
                                    </Box>
                                  ))}
                                  {vendorConfig.length > TAG_COUNT && (
                                    <Typography
                                      variant="caption"
                                      sx={{
                                        color: 'text.secondary',
                                        fontSize: '0.7rem',
                                        fontStyle: 'italic',
                                        px: 0.5,
                                      }}>
                                      +{vendorConfig.length - TAG_COUNT} more
                                    </Typography>
                                  )}
                                </Box>
                              );
                            })()}
                          </Box>
                        </Stack>
                      </Stack>
                    </Stack>

                    <Divider />
                    <Stack
                      sx={{
                        gap: 1,
                        justifyContent: 'space-between',
                        flexWrap: 'nowrap',
                        flexDirection: 'row',
                        alignItems: 'center',
                      }}>
                      <Box
                        component="div"
                        onClick={() => onClickSubscription(subscription)}
                        sx={{
                          display: 'flex',
                          gap: {
                            xs: 0.5,
                            md: 1,
                          },
                          flexDirection: 'row',
                          flexWrap: 'wrap',
                        }}>
                        <Typography variant={isMobile ? 'subtitle2' : 'subtitle1'} sx={{ whiteSpace: 'nowrap' }}>
                          {formatPrice(
                            // @ts-ignore
                            subscription.items?.[0]?.price,
                            subscription.paymentCurrency,
                            subscription.items?.[0]?.price?.product?.unit_label
                          )}
                        </Typography>
                        {subscriptionTime && (
                          <Typography
                            variant="body2"
                            sx={{
                              color: 'text.secondary',
                            }}>
                            ({subscriptionTime})
                          </Typography>
                        )}
                      </Box>
                      <SubscriptionActions
                        subscription={subscription}
                        onChange={(v) => {
                          reload();
                          if (onChange) {
                            onChange(v);
                          }
                        }}
                        showUnsubscribe={false}
                        showRecharge={!isWillCanceled(subscription)}
                        showBalanceInfo
                        includeActions={['recharge']}
                        actionProps={{
                          recharge: {
                            variant: 'text',
                            color: 'primary',
                            sx: {
                              whiteSpace: 'nowrap',
                            },
                          },
                        }}
                      />
                    </Stack>
                  </Stack>
                  <Stack
                    sx={{
                      display: 'flex',
                      justifyContent: 'flex-end',
                      '.action-button': {
                        flex: 1,
                      },
                    }}>
                    <SubscriptionActions
                      subscription={subscription}
                      onChange={(v) => {
                        reload();
                        if (onChange) {
                          onChange(v);
                        }
                      }}
                      forceShowDetailAction
                      showUnsubscribe={false}
                      excludeActions={['recharge']}
                      actionProps={{
                        cancel: {
                          variant: 'outlined',
                          color: 'primary',
                        },
                        recover: {
                          variant: 'outlined',
                          color: 'info',
                        },
                        pastDue: {
                          variant: 'outlined',
                          color: 'primary',
                        },
                        detail: {
                          variant: 'contained',
                          sx: {
                            color: 'text.primary',

                            backgroundColor: 'grey.100',
                            '&:hover': {
                              backgroundColor: 'grey.200',
                            },
                          },
                        },
                        menu: {
                          sx: {
                            color: 'text.primary',
                          },
                        },
                      }}
                      mode="menu-only"
                      buttonSize="medium"
                    />
                  </Stack>
                </Stack>
              );
            })}
          </Stack>
          {hasMore && !isMobile && showLoadingMore && (
            <Box
              sx={{
                alignItems: 'center',
                gap: 0.5,
                display: 'flex',
                mt: 0.5,
              }}>
              {t('common.loadingMore', { resource: t('admin.subscriptions') })}
            </Box>
          )}
          {isMobile && (
            <Box>
              {hasMore && (
                <Button variant="text" type="button" color="inherit" onClick={loadMore} disabled={loadingMore}>
                  {loadingMore
                    ? t('common.loadingMore', { resource: t('admin.subscriptions') })
                    : t('common.loadMore', { resource: t('admin.subscriptions') })}
                </Button>
              )}
              {!hasMore && data.count > pageSize && (
                <Typography
                  sx={{
                    color: 'text.secondary',
                  }}>
                  {t('common.noMore', { resource: t('admin.subscriptions') })}
                </Typography>
              )}
            </Box>
          )}
        </>
      ) : (
        <Empty>
          {onlyActive && hasAnySubscriptions ? (
            <Box sx={{ textAlign: 'center' }}>
              <Typography>{t('admin.subscription.noActiveEmpty')}</Typography>
              {changeActive && (
                <Button onClick={() => changeActive(false)} variant="text" sx={{ color: 'text.link' }}>
                  {t('admin.subscription.viewAll')}
                </Button>
              )}
            </Box>
          ) : (
            t('admin.subscription.empty')
          )}
        </Empty>
      )}
    </Stack>
  );
}
