/* eslint-disable react/no-unstable-nested-components */
import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
import { isValid } from '@arcblock/did';
import Toast from '@arcblock/ux/lib/Toast';
import {
  Amount,
  Status,
  TxGas,
  TxLink,
  api,
  formatBNStr,
  formatError,
  formatTime,
  getCustomerAvatar,
  getPayoutStatusColor,
  getUserProfileLink,
  useMobile,
} from '@blocklet/payment-react';
import type { TCustomer, TPayoutExpanded } from '@blocklet/payment-types';
import { ArrowBackOutlined, InfoOutlined } from '@mui/icons-material';
import { Alert, Avatar, Box, Button, CircularProgress, Divider, Stack, Tooltip, Typography } from '@mui/material';
import { styled } from '@mui/system';
import { useRequest, useSetState } from 'ahooks';
import { Link } from 'react-router-dom';

import DID from '@arcblock/ux/lib/DID';
import Copyable from '../../../../components/copyable';
import CustomerLink from '../../../../components/customer/link';
import EventList from '../../../../components/event/list';
import InfoMetric from '../../../../components/info-metric';
import InfoRow from '../../../../components/info-row';
import MetadataEditor from '../../../../components/metadata/editor';
import MetadataList from '../../../../components/metadata/list';
import SectionHeader from '../../../../components/section/header';
import { getAppInfo, goBackOrFallback } from '../../../../libs/util';
import InfoCard from '../../../../components/info-card';
import InfoRowGroup from '../../../../components/info-row-group';

const fetchData = (
  id: string
): Promise<
  TPayoutExpanded & {
    paymentIntent?: { customer: TCustomer };
  }
> => {
  return api.get(`/api/payouts/${id}`).then((res: any) => res.data);
};

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

export default function PayoutDetail(props: { id: string }) {
  const { t, locale } = useLocaleContext();
  const { isMobile } = useMobile();
  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: TPayoutExpanded) => {
    try {
      setState((prev) => ({ loading: { ...prev.loading, [key]: true } }));
      await api.put(`/api/payouts/${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 currency = data.paymentCurrency;
  const total = [formatBNStr(data?.amount, currency.decimal), currency.symbol].join(' ');

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

  const { paymentIntent } = data || {};

  const renderCustomer = () => {
    if (data.customer) {
      return <CustomerLink customer={data.customer} />;
    }
    const appInfo = getAppInfo(data.destination);
    if (appInfo) {
      return (
        <InfoCard name={appInfo.name} description={<DID did={data.destination} />} logo={appInfo.avatar} size={40} />
      );
    }
    return data.destination;
  };

  const isAnonymousPayer = paymentIntent?.customer?.metadata?.anonymous;

  const customerDid = paymentIntent?.customer?.did || paymentIntent?.metadata?.payerDid || '';

  return (
    <Root direction="column" spacing={2.5} mb={4}>
      <Box>
        <Stack
          className="page-header"
          direction="row"
          sx={{
            justifyContent: 'space-between',
            alignItems: 'center',
          }}>
          <Stack
            direction="row"
            onClick={() => goBackOrFallback('/admin/payments/payouts')}
            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.payouts')}
            </Typography>
          </Stack>
        </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"
              sx={{
                alignItems: 'center',
              }}>
              <Stack
                direction="row"
                spacing={1}
                sx={{
                  alignItems: 'center',
                }}>
                <Avatar
                  src={data.paymentCurrency.logo}
                  alt={data.paymentCurrency.symbol}
                  variant="square"
                  sx={{ width: '52px', height: '52px', borderRadius: 0.5 }}
                />
                <Stack
                  direction="column"
                  sx={{
                    alignItems: 'flex-start',
                    justifyContent: 'space-around',
                  }}>
                  <Amount amount={total} sx={{ my: 0, fontSize: '1.75rem', lineHeight: '32px' }} />
                  <Copyable text={props.id} />
                </Stack>
              </Stack>
            </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.status')}
              value={<Status label={data.status} color={getPayoutStatusColor(data.status)} />}
              divider
            />
            {paymentIntent?.id && (
              <InfoMetric
                label={t('customer.payout.payer')}
                value={
                  <InfoCard
                    variant="circular"
                    logo={getCustomerAvatar(
                      paymentIntent?.customer?.did,
                      paymentIntent?.customer?.updated_at
                        ? new Date(paymentIntent?.customer?.updated_at).toISOString()
                        : '',
                      48
                    )}
                    logoName={paymentIntent?.customer?.metadata?.anonymous ? '' : paymentIntent?.customer?.name}
                    name={
                      <Typography
                        variant="subtitle2"
                        sx={{
                          ...(isAnonymousPayer
                            ? {}
                            : {
                                cursor: 'pointer',
                                '&:hover': {
                                  color: 'text.link',
                                },
                              }),
                        }}
                        onClick={() => {
                          if (isAnonymousPayer) {
                            return;
                          }
                          const url = getUserProfileLink(paymentIntent?.customer?.did, locale);
                          window.open(url, '_blank');
                        }}>
                        {paymentIntent?.customer?.name}
                        {paymentIntent?.customer?.email ? ` (${paymentIntent?.customer?.email})` : ''}
                      </Typography>
                    }
                    description={
                      isValid(customerDid) && (
                        <DID did={customerDid} {...(isMobile ? { responsive: false, compact: true } : {})} />
                      )
                    }
                    size={40}
                  />
                }
                divider
              />
            )}
            {/* <InfoMetric label={t('common.createdAt')} value={formatTime(data.created_at)} divider /> */}
            {/* <InfoMetric label={t('common.updatedAt')} value={formatTime(data.updated_at)} 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" sx={{ containerType: 'inline-size' }}>
            <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.status')}
                value={
                  <Stack
                    direction="row"
                    spacing={1}
                    sx={{
                      alignItems: 'center',
                    }}>
                    <Status label={data.status} color={getPayoutStatusColor(data.status)} />
                    {data.last_attempt_error && (
                      <Tooltip
                        title={
                          <pre style={{ whiteSpace: 'break-spaces' }}>
                            {JSON.stringify(data.last_attempt_error, null, 2)}
                          </pre>
                        }>
                        <InfoOutlined fontSize="small" color="error" />
                      </Tooltip>
                    )}
                  </Stack>
                }
              />
              <InfoRow label={t('common.amount')} value={total} />
              <InfoRow label={t('common.customer')} value={renderCustomer()} />
              <InfoRow label={t('common.createdAt')} value={formatTime(data.created_at)} />
              <InfoRow label={t('common.description')} value={data.description} />
              <InfoRow label={t('common.updatedAt')} value={formatTime(data.updated_at)} />
            </InfoRowGroup>
          </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>
        </Box>
        {isMobile && <Divider />}
        <Box className="payment-link-column-2" sx={{ gap: 2.5, display: 'flex', flexDirection: 'column' }}>
          <Box className="section">
            <SectionHeader title={t('admin.paymentMethod._name')} />
            <Stack>
              <InfoRow
                label={t('common.id')}
                value={data.paymentMethod?.id}
                direction={InfoDirection}
                alignItems={InfoAlignItems}
              />
              <InfoRow
                label={t('admin.paymentMethod.type')}
                value={data.paymentMethod?.type}
                direction={InfoDirection}
                alignItems={InfoAlignItems}
              />
              <InfoRow
                label={t('admin.paymentCurrency.name')}
                value={`${data.paymentCurrency.symbol} (${data.paymentMethod?.name})`}
                direction={InfoDirection}
                alignItems={InfoAlignItems}
              />
              {(!!data.payment_details?.ethereum || !!data.payment_details?.base) && (
                <InfoRow
                  label={t('common.txGas')}
                  value={<TxGas details={data.payment_details as any} method={data.paymentMethod} />}
                  direction={InfoDirection}
                  alignItems={InfoAlignItems}
                />
              )}
              <InfoRow
                label={t(`common.${data.payment_details?.arcblock?.type || 'transfer'}TxHash`)}
                value={<TxLink details={data.payment_details as any} method={data.paymentMethod} />}
                direction={InfoDirection}
                alignItems={InfoAlignItems}
              />
            </Stack>
          </Box>
          <Divider />
          <Box className="section">
            <SectionHeader title={t('admin.connections')} />
            <Stack>
              {data.payment_intent_id ? (
                <InfoRow
                  label={t('admin.paymentIntent.name')}
                  value={<Link to={`/admin/payments/${data.paymentIntent.id}`}>{data.paymentIntent.id}</Link>}
                  direction={InfoDirection}
                  alignItems={InfoAlignItems}
                />
              ) : (
                t('common.none')
              )}
            </Stack>
          </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.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>
    </Root>
  );
}

const Root = styled(Stack)``;
