/* eslint-disable react/no-unstable-nested-components */
import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
import Toast from '@arcblock/ux/lib/Toast';
import {
  api,
  formatBNStr,
  formatError,
  formatTime,
  getCustomerAvatar,
  useMobile,
  usePaymentContext,
} from '@blocklet/payment-react';
import type { GroupedBN, TCustomerExpanded, TPaymentMethodExpanded } from '@blocklet/payment-types';
import { ArrowBackOutlined } from '@mui/icons-material';
import { Alert, Avatar, Box, Button, CircularProgress, Divider, Stack, Typography } from '@mui/material';
import { styled } from '@mui/system';
import { useRequest, useSetState } from 'ahooks';
import { defaultCountries, FlagEmoji, parseCountry } from 'react-international-phone';

import { useMemo } from 'react';
import SafeDidAddress from '../../../../components/safe-did-address';
import BalanceList from '../../../../components/balance-list';
import Copyable from '../../../../components/copyable';
import EditCustomer from '../../../../components/customer/edit';
import CreditOverview from '../../../../components/customer/credit-overview';
import EventList from '../../../../components/event/list';
import InfoMetric from '../../../../components/info-metric';
import InfoRow from '../../../../components/info-row';
import InvoiceList from '../../../../components/invoice/list';
import MetadataEditor from '../../../../components/metadata/editor';
import PaymentList from '../../../../components/payment-intent/list';
import PayoutList from '../../../../components/payouts/list';
import RefundList from '../../../../components/refund/list';
import SectionHeader from '../../../../components/section/header';
import SubscriptionList from '../../../../components/subscription/list';
import { goBackOrFallback } from '../../../../libs/util';
import MetadataList from '../../../../components/metadata/list';
import InfoRowGroup from '../../../../components/info-row-group';

const fetchData = async (
  id: string
): Promise<{
  customer: TCustomerExpanded;
  summary: { [key: string]: GroupedBN };
}> => {
  const [customer, summary] = await Promise.all([
    api.get(`/api/customers/${id}`).then((res: any) => res.data),
    api.get(`/api/customers/${id}/summary`).then((res: any) => res.data),
  ]);

  return {
    customer,
    summary,
  };
};

const InfoDirection = 'column';
const InfoAlignItems = 'flex-start';

function getTokenBalances(customer: TCustomerExpanded, paymentMethods: TPaymentMethodExpanded[]) {
  const tokens: { currency: string; balance: string }[] = [];
  // @ts-ignore
  const currencies = paymentMethods.reduce((acc, x) => acc.concat(x.payment_currencies), []);

  if (customer.balance) {
    tokens.push({
      currency: 'USD',
      balance: formatBNStr(customer.balance, 2),
    });
  }

  if (customer.token_balance) {
    Object.keys(customer.token_balance).forEach((currencyId) => {
      const currency = currencies.find((x: any) => x.id === currencyId);
      // @ts-ignore
      if (currency && customer.token_balance[currencyId] !== '0') {
        tokens.push({
          // @ts-ignore
          currency: currency.symbol,
          // @ts-ignore
          balance: formatBNStr(customer.token_balance[currencyId], currency.decimal),
        });
      }
    });
  }

  return tokens;
}

export default function CustomerDetail(props: { id: string }) {
  const { t } = useLocaleContext();
  const { isMobile } = useMobile();
  const { settings, livemode } = usePaymentContext();
  const [state, setState] = useSetState({
    adding: {
      price: false,
    },
    editing: {
      metadata: false,
      customer: false,
    },
    loading: {
      metadata: false,
      customer: false,
    },
  });

  const { loading, error, data, runAsync } = useRequest(() => fetchData(props.id));
  const countryDetail = useMemo(() => {
    const item = defaultCountries.find((v) => v[1] === data?.customer?.address?.country);
    return item ? parseCountry(item) : { name: '' };
  }, [data]);
  if (error) {
    return <Alert severity="error">{error.message}</Alert>;
  }

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

  const onUpdateMetadata = async (updates: TCustomerExpanded) => {
    try {
      setState((prev) => ({ loading: { ...prev.loading, metadata: true } }));
      await api.put(`/api/customers/${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, metadata: false } }));
    }
  };

  const onUpdateInfo = async (updates: TCustomerExpanded) => {
    try {
      setState((prev) => ({ loading: { ...prev.loading, customer: true } }));
      await api.put(`/api/customers/${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, customer: false } }));
    }
  };

  // const onChange = (action: string) => {
  //   if (action === 'remove') {
  //     navigate('/admin/customers');
  //   } else {
  //     runAsync();
  //   }
  // };

  const tokenBalances = getTokenBalances(data.customer, settings.paymentMethods);
  const handleEditMetadata = () => {
    setState((prev) => ({ editing: { ...prev.editing, metadata: true } }));
  };

  return (
    <Root direction="column" spacing={2.5} sx={{ mb: 4 }}>
      <Box>
        <Stack
          className="page-header"
          direction="row"
          sx={{
            justifyContent: 'space-between',
            alignItems: 'center',
          }}>
          <Stack
            direction="row"
            onClick={() => goBackOrFallback('/admin/customers')}
            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.customers')}
            </Typography>
          </Stack>
          <Button
            variant="outlined"
            color="primary"
            size="small"
            disabled={state.editing.customer}
            onClick={() => setState((prev) => ({ editing: { ...prev.editing, customer: true } }))}>
            {t('common.edit')}
          </Button>
          {/* <CustomerActions data={data.customer} 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',
            }}>
            <Stack
              direction="row"
              spacing={1}
              sx={{
                alignItems: 'center',
              }}>
              <Avatar
                title={data.customer.name}
                src={getCustomerAvatar(
                  data.customer?.did,
                  data.customer?.updated_at ? new Date(data.customer.updated_at).toISOString() : '',
                  52
                )}
                alt={data.customer.name}
                variant="circular"
                sx={{ width: 52, height: 52 }}
              />
              <Typography variant="h2" sx={{ fontWeight: 600 }}>
                {data.customer.name}
              </Typography>
            </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('admin.customer.email')} value={data.customer.email} divider />
            <InfoMetric label={t('admin.customer.phone')} value={data.customer.phone} divider />
            <InfoMetric label={t('common.id')} value={<Copyable text={props.id} style={{ marginLeft: 4 }} />} divider />
          </Stack>
        </Box>
        <Divider />
      </Box>
      <Stack
        sx={{
          flexDirection: {
            xs: 'column',
            lg: 'row',
          },
          gap: {
            xs: 2.5,
            md: 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, gap: 2.5, display: 'flex', flexDirection: 'column' }}>
          {/* 信用管理区域 */}
          <Box className="section">
            <SectionHeader title={t('admin.creditGrants.title')} mb={0} />
            <CreditOverview customerId={props.id} settings={settings} mode="dashboard" />
          </Box>
          <Divider />

          <Box className="section" sx={{ containerType: 'inline-size' }}>
            <SectionHeader title={t('admin.details')} />
            <InfoRowGroup
              sx={{
                display: 'grid',
                gridTemplateColumns: {
                  xs: 'repeat(1, 1fr)',
                  xxl: 'repeat(2, 1fr)',
                },
                '@container (min-width: 1050px)': {
                  gridTemplateColumns: 'repeat(2, 1fr)',
                },
                '.info-row-wrapper': {
                  gap: 1,
                  flexDirection: {
                    xs: 'column',
                    xxl: 'row',
                  },
                  alignItems: {
                    xs: 'flex-start',
                    xxl: 'center',
                  },
                  '@container (min-width: 1050px)': {
                    flexDirection: 'row',
                    alignItems: 'center',
                  },
                },
              }}>
              <InfoRow
                label={t('common.did')}
                value={<SafeDidAddress did={data.customer.did} chainId={livemode ? 'main' : 'beta'} showQrcode />}
              />
              <InfoRow label={t('admin.customer.name')} value={data.customer.name} />
              <InfoRow label={t('common.createdAt')} value={formatTime(data.customer.created_at)} />

              <InfoRow label={t('admin.customer.invoicePrefix')} value={data.customer.invoice_prefix} />
              {(data.customer as any).google_play_uuid && (
                <InfoRow label={t('admin.customer.googlePlayUuid')} value={(data.customer as any).google_play_uuid} />
              )}
              {(data.customer as any).app_store_uuid && (
                <InfoRow label={t('admin.customer.appStoreUuid')} value={(data.customer as any).app_store_uuid} />
              )}
              <InfoRow label={t('common.updatedAt')} value={formatTime(data.customer.updated_at)} />
              {state.editing.customer && (
                <EditCustomer
                  data={data.customer}
                  loading={state.loading.customer}
                  onSave={onUpdateInfo}
                  onCancel={() => setState((prev) => ({ editing: { ...prev.editing, customer: false } }))}
                />
              )}
            </InfoRowGroup>
          </Box>
          <Divider />
          <Box className="section">
            <SectionHeader title={t('admin.subscriptions')} mb={0} />
            <Box className="section-body">
              <SubscriptionList
                features={{ customer: false, toolbar: false }}
                customer_id={data.customer.id}
                status={['active', 'trialing', 'paused', 'past_due', 'canceled'].join(',')}
              />
            </Box>
          </Box>
          <Divider />
          <Box className="section">
            <SectionHeader title={t('admin.invoices')} mb={0} />
            <Box className="section-body">
              <InvoiceList
                features={{ customer: false, toolbar: false }}
                customer_id={data.customer.id}
                status={['open', 'paid', 'uncollectible', 'draft', 'void'].join(',')}
                include_staking
              />
            </Box>
          </Box>
          <Divider />
          <Box className="section">
            <SectionHeader title={t('admin.payments')} mb={0} />
            <Box className="section-body">
              <PaymentList features={{ customer: false, toolbar: false }} customer_id={data.customer.id} />
            </Box>
          </Box>
          <Divider />
          <Box className="section">
            <SectionHeader title={t('admin.payouts')} mb={0} />
            <Box className="section-body">
              <PayoutList
                features={{ customer: false, toolbar: false }}
                customer_id={data.customer.id}
                status={['paid', 'pending', 'failed', 'canceled'].join(',')}
              />
            </Box>
          </Box>
          <Divider />
          <Box className="section">
            <SectionHeader title={t('admin.refunds')} mb={0} />
            <Box className="section-body">
              <RefundList
                features={{ customer: false, toolbar: false }}
                customer_id={data.customer.id}
                status={['succeeded', 'canceled', 'failed', 'requires_action', 'pending'].join(',')}
              />
            </Box>
          </Box>
          <Divider />
          <Box className="section">
            <SectionHeader title={t('admin.events.title')} />
            <Box className="section-body">
              <EventList features={{ toolbar: false }} object_id={data.customer.id} />
            </Box>
          </Box>
        </Box>
        {isMobile && <Divider />}
        <Box className="payment-link-column-2" sx={{ gap: 2.5, display: 'flex', flexDirection: 'column' }}>
          <Box className="section">
            <SectionHeader title={t('admin.metrics')} />
            <Box className="section-body" sx={{ '.info-row-value': { width: '100%' } }}>
              <InfoRow
                label={t('admin.customer.spent')}
                value={<BalanceList data={data.summary?.paid} showLogo />}
                direction={InfoDirection}
                alignItems={InfoAlignItems}
              />
              <InfoRow
                label={t('admin.customer.stake')}
                value={<BalanceList data={data.summary?.stake} showLogo />}
                direction={InfoDirection}
                alignItems={InfoAlignItems}
              />
              <InfoRow
                label={t('admin.customer.token')}
                value={<BalanceList data={data.summary?.token} showLogo />}
                direction={InfoDirection}
                alignItems={InfoAlignItems}
              />
              <InfoRow
                label={t('admin.customer.due')}
                value={<BalanceList data={data.summary?.due} showLogo />}
                direction={InfoDirection}
                alignItems={InfoAlignItems}
              />
              <InfoRow
                label={t('admin.customer.refund')}
                value={<BalanceList data={data.summary?.refunded} showLogo />}
                direction={InfoDirection}
                alignItems={InfoAlignItems}
              />
              {tokenBalances.map((x) => (
                <InfoRow
                  key={x.currency}
                  label={t('admin.customer.balance', { currency: x.currency })}
                  value={x.balance}
                  direction={InfoDirection}
                  alignItems={InfoAlignItems}
                />
              ))}
            </Box>
          </Box>
          <Divider />
          <Box className="section">
            <SectionHeader title={t('admin.customer.address.label')} />
            <Box className="section-body">
              <InfoRow
                label={t('admin.customer.address.country')}
                value={
                  data.customer.address?.country ? (
                    <Box
                      sx={{
                        display: 'flex',
                        alignItems: 'center',
                        flexWrap: 'nowrap',
                        gap: 0.5,
                        cursor: 'pointer',
                      }}>
                      <FlagEmoji iso2={data.customer.address?.country} style={{ display: 'flex', width: 24 }} />
                      <Typography>{countryDetail?.name}</Typography>
                    </Box>
                  ) : (
                    ''
                  )
                }
                direction={InfoDirection}
                alignItems={InfoAlignItems}
              />
              <InfoRow
                label={t('admin.customer.address.state')}
                value={data.customer.address?.state}
                direction={InfoDirection}
                alignItems={InfoAlignItems}
              />
              <InfoRow
                label={t('admin.customer.address.city')}
                value={data.customer.address?.city}
                direction={InfoDirection}
                alignItems={InfoAlignItems}
              />
              <InfoRow
                label={t('admin.customer.address.line1')}
                value={data.customer.address?.line1}
                direction={InfoDirection}
                alignItems={InfoAlignItems}
              />
              <InfoRow
                label={t('admin.customer.address.line2')}
                value={data.customer.address?.line2}
                direction={InfoDirection}
                alignItems={InfoAlignItems}
              />
              <InfoRow
                label={t('admin.customer.address.postal_code')}
                value={data.customer.address?.postal_code}
                direction={InfoDirection}
                alignItems={InfoAlignItems}
              />
            </Box>
          </Box>
          <Divider />
          <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.customer.metadata} handleEditMetadata={handleEditMetadata} />
              {state.editing.metadata && (
                <MetadataEditor
                  data={data.customer}
                  loading={state.loading.metadata}
                  onSave={onUpdateMetadata}
                  onCancel={() => setState((prev) => ({ editing: { ...prev.editing, metadata: false } }))}
                />
              )}
            </Box>
          </Box>
        </Box>
      </Stack>
    </Root>
  );
}

const Root = styled(Stack)``;
