import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
import Toast from '@arcblock/ux/lib/Toast';
import { api, formatError, getPrefix } from '@blocklet/payment-react';
import type { TPaymentCurrency, TPaymentMethodExpanded } from '@blocklet/payment-types';
import { AddOutlined } from '@mui/icons-material';
import {
  Button,
  CircularProgress,
  TextField,
  Autocomplete,
  Box,
  Typography,
  Avatar,
  Stack,
  Divider,
} from '@mui/material';
import { useSetState } from 'ahooks';
import { FormProvider, useForm } from 'react-hook-form';
import { dispatch } from 'use-bus';
import { useEffect } from 'react';
import { joinURL } from 'ufo';
import DrawerForm from '../drawer-form';
import PaymentCurrencyForm from './form';

const loadTokenList = () =>
  import(
    /* webpackChunkName: "payment-token-list" */
    './tokenList.json'
  );
interface TokenInfo {
  address: string;
  chainId: number;
  decimals: number;
  name: string;
  symbol: string;
  logoURI?: string;
  localLogoURI?: string;
}

export default function PaymentCurrencyAdd({
  method,
  onClose,
}: {
  method: TPaymentMethodExpanded;
  onClose: () => void;
}) {
  const { t } = useLocaleContext();
  const [state, setState] = useSetState<{
    loading: boolean;
    tokenListLoading: boolean;
    availableTokens: TokenInfo[];
  }>({
    loading: false,
    tokenListLoading: false,
    availableTokens: [],
  });

  const methods = useForm<TPaymentCurrency>({
    defaultValues: {
      payment_method_id: method.id,
      name: '',
      description: '',
      logo: '',
      contract: '',
    },
  });
  const { handleSubmit, setValue } = methods;

  const showTokenSelect = ['ethereum', 'base'].includes(method.type);

  // @ts-ignore
  const chainId = method?.settings?.[method.type]?.chain_id || '';

  useEffect(() => {
    if (showTokenSelect && !state.availableTokens.length) {
      setState({ tokenListLoading: true });
      loadTokenList().then((module) => {
        const availableTokens = showTokenSelect
          ? // @ts-ignore
            ((module.default?.[chainId] as TokenInfo[]) || []).filter(
              (token: TokenInfo) => !(method.payment_currencies || []).find((c: any) => c.contract === token.address)
            )
          : [];
        setState({
          availableTokens,
          tokenListLoading: false,
        });
      });
    }
  }, [showTokenSelect, chainId]);

  const getLogoURI = (token: TokenInfo) => {
    if (token.localLogoURI) {
      return joinURL(getPrefix(), token.localLogoURI);
    }
    return token.logoURI || '';
  };

  const handleTokenSelect = (token: TokenInfo | null) => {
    if (token) {
      setValue('name', token.name);
      setValue('description', `${token.name} (${token.symbol})`);
      setValue('logo', getLogoURI(token));
      setValue('contract', token.address);
    }
  };

  const onSubmit = (data: TPaymentCurrency) => {
    setState({ loading: true });
    api
      .post('/api/payment-currencies', data)
      .then(() => {
        setState({ loading: false });
        Toast.success(t('admin.paymentCurrency.saved'));
        methods.reset();
        dispatch('drawer.submitted');
        dispatch('paymentCurrency.added');
      })
      .catch((err: any) => {
        setState({ loading: false });
        console.error(err);
        Toast.error(formatError(err));
      });
  };

  return (
    <DrawerForm
      open
      icon={<AddOutlined />}
      onClose={onClose}
      text={t('admin.paymentCurrency.add')}
      width={640}
      footer={
        <Button
          variant="contained"
          size="large"
          onClick={handleSubmit(onSubmit)}
          disabled={state.loading}
          sx={{ width: '100%' }}>
          {state.loading && <CircularProgress size={20} />} {t('common.save')}
        </Button>
      }>
      <FormProvider {...methods}>
        {showTokenSelect && (
          <Box sx={{ mb: 3 }}>
            <Autocomplete
              disablePortal
              options={state.availableTokens}
              loading={state.tokenListLoading}
              getOptionLabel={(option: TokenInfo) => option.symbol}
              onChange={(_, value) => handleTokenSelect(value)}
              renderInput={(params) => (
                <TextField
                  {...params}
                  label={t('admin.paymentCurrency.quickAdd')}
                  placeholder={t('admin.paymentCurrency.searchToken')}
                  fullWidth
                />
              )}
              renderOption={(props, option) => (
                <Box
                  component="li"
                  {...props}
                  sx={{
                    display: 'flex',
                    alignItems: 'center',
                    gap: 1,
                    cursor: 'pointer',
                    '&:hover': {
                      backgroundColor: 'action.hover',
                    },
                  }}>
                  <Avatar
                    src={getLogoURI(option) || option.symbol}
                    alt={option.symbol}
                    sx={{
                      width: 24,
                      height: 24,
                    }}
                  />
                  <Stack>
                    <Typography
                      sx={{
                        fontWeight: 500,
                      }}>
                      {option.name}
                    </Typography>
                    <Typography
                      variant="caption"
                      sx={{
                        color: 'text.secondary',
                      }}>
                      {option.symbol}
                    </Typography>
                  </Stack>
                </Box>
              )}
              isOptionEqualToValue={(option, value) => option.address === value.address}
            />
            <Divider sx={{ my: 3 }}>
              <Typography
                variant="caption"
                sx={{
                  color: 'text.secondary',
                }}>
                {t('admin.paymentCurrency.orManualInput')}
              </Typography>
            </Divider>
          </Box>
        )}
        <PaymentCurrencyForm />
      </FormProvider>
    </DrawerForm>
  );
}
