import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
import Toast from '@arcblock/ux/lib/Toast';
import type { TPricingTableExpanded } from '@blocklet/payment-types';
import { Alert, CircularProgress, Stack, Typography } from '@mui/material';
import { Box } from '@mui/system';
import { useRequest } from 'ahooks';
import { useState } from 'react';

import Livemode from '../components/livemode';
import PricingTable from '../components/pricing-table';
import api from '../libs/api';
import { mergeExtraParams } from '../libs/util';
import type { CheckoutProps } from '../types';
import CheckoutForm from './form';
import { PaymentThemeProvider } from '../theme';
import TruncatedText from '../components/truncated-text';

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

const ensureProtocol = (url: string): string => {
  if (!/^https?:\/\//i.test(url)) {
    return `https://${url}`;
  }
  return url;
};

function CheckoutTableInner({ id, mode, onPaid, onError, onChange, extraParams, goBack, theme }: CheckoutProps) {
  if (!id.startsWith('prctbl_')) {
    throw new Error('A valid pricing table id is required.');
  }

  const [sessionId, setSessionId] = useState('');
  const hashSessionId = window.location.hash.slice(1);

  const { t } = useLocaleContext();
  const { error, loading, data } = useRequest(() => fetchData(id));

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

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

  if (data.items.length === 0) {
    return <Alert severity="warning">{t('payment.checkout.noPricing')}</Alert>;
  }

  const handleSelect = (priceId: string, currencyId: string) => {
    api
      .post(
        `/api/pricing-tables/${data.id}/checkout/${priceId}?${mergeExtraParams({
          ...extraParams,
          currencyId,
        })}`
      )
      .then((res: any) => {
        if (mode === 'standalone') {
          let { url } = res.data;
          url = url.indexOf('?') > -1 ? `${url}&currencyId=${currencyId}` : `${url}?currencyId=${currencyId}`;
          window.location.replace(ensureProtocol(url));
        } else {
          window.location.hash = res.data.id;
          setSessionId(res.data.id);
        }
      })
      .catch((err: any) => {
        console.error(err);
        Toast.error(err.message);
      });
  };

  const prop: any = {};

  if (goBack) {
    prop.goBack = () => {
      window.location.hash = '';
      if (typeof goBack !== 'undefined') {
        goBack();
      }
      setSessionId('');
    };
  }

  if (!sessionId && !hashSessionId) {
    if (mode === 'standalone') {
      return (
        <Stack
          direction="column"
          sx={{
            alignItems: 'center',
            overflow: {
              xs: 'auto',
              md: 'hidden',
            },
            height: '100%',
            pt: {
              xs: 2.5,
              md: 7.5,
            },
            px: 2.5,
          }}>
          <Box
            sx={{
              display: 'flex',
              flexDirection: 'column',
              fontSize: '24px',
              alignItems: 'center',
              margin: {
                xs: '20px 0',
                md: '20px 20px',
              },
              maxWidth: {
                xs: '100%',
                md: 400,
              },
              textAlign: 'center',
            }}>
            {!data.livemode && <Livemode sx={{ display: 'flex', marginBottom: '8px', width: 'fit-content', ml: 0 }} />}
            <Typography
              sx={{
                color: 'text.primary',
                fontWeight: 600,
                lineHeight: '32px',
                fontSize: '24px',
              }}>
              <TruncatedText text={data.name} maxLength={60} useWidth />
            </Typography>
          </Box>
          <PricingTable table={data} onSelect={handleSelect} />
        </Stack>
      );
    }

    return <PricingTable mode="select" table={data} onSelect={handleSelect} />;
  }

  return (
    <Box sx={{ height: '100%' }}>
      <CheckoutForm
        id={hashSessionId || sessionId}
        mode={mode}
        onPaid={onPaid}
        onError={onError}
        onChange={onChange}
        theme={theme}
        {...prop}
      />
    </Box>
  );
}

export default function CheckoutTable(props: CheckoutProps) {
  if (props.theme === 'inherit') {
    return <CheckoutTableInner {...props} />;
  }
  if (props.theme && typeof props.theme === 'object') {
    return (
      <PaymentThemeProvider theme={props.theme}>
        <CheckoutTableInner {...props} />
      </PaymentThemeProvider>
    );
  }
  return (
    <PaymentThemeProvider>
      <CheckoutTableInner {...props} />
    </PaymentThemeProvider>
  );
}
