import { isValidElement } from 'react';
import PropTypes from 'prop-types';
import { Box, Tooltip, Typography, useTheme } from '@mui/material';
import { Icon } from '@iconify/react';
import closeRoundedIcon from '@iconify-icons/material-symbols/close-rounded';
import hourglassEmptyRoundedIcon from '@iconify-icons/material-symbols/hourglass-empty-rounded';
import ruleSettingsRoundedIcon from '@iconify-icons/material-symbols/rule-settings-rounded';
import LoadingMask from '@arcblock/ux/lib/LoadingMask';
import Success from '@arcblock/ux/lib/Success';
import noop from 'lodash/noop';
import { useMemoizedFn } from 'ahooks';
import { translate } from '@arcblock/ux/lib/Locale/util';
import ProviderIcon from '@arcblock/ux/lib/DIDConnect/provider-icon';
import { LOGIN_PROVIDER } from '@arcblock/ux/lib/Util/constant';

import translations from '../assets/locale';
import ActionButton from './action-button';
import BackButton from './back-button';

function BaseStatus({ icon = null, title = '', color = '', description = '', extraContent = null, actions = null }) {
  const { palette } = useTheme();
  const fgColor = color || palette.grey[700];

  return (
    <Box
      sx={{
        display: 'flex',
        flexDirection: 'column',
        alignItems: 'center',
        justifyContent: 'center',
        gap: 1.5,
      }}>
      {isValidElement(icon) ? (
        icon
      ) : (
        <Box
          sx={{
            backgroundColor: fgColor,
            borderRadius: '100%',
            fontSize: 0,
          }}>
          <Icon
            icon={icon}
            fontSize={52}
            style={{
              transform: 'scale(0.7)',
              color: palette.primary.contrastText,
            }}
          />
        </Box>
      )}

      <Box sx={{ textAlign: 'center' }}>
        <Typography
          variant="h6"
          sx={{
            fontWeight: 500,
            color: fgColor,
          }}>
          {title}
        </Typography>
        <Tooltip title={description} placement="top">
          <Typography
            variant="body2"
            sx={{
              color: 'text.secondary',
              overflow: 'hidden',
              display: '-webkit-box',
              '-webkit-box-orient': 'vertical',
              '-webkit-line-clamp': '3',
              whiteSpace: 'pre-wrap',
              wordBreak: 'break-word',
            }}>
            {description}
          </Typography>
        </Tooltip>
      </Box>
      {extraContent}
      <Box>{actions}</Box>
    </Box>
  );
}

BaseStatus.propTypes = {
  icon: PropTypes.any,
  title: PropTypes.string,
  color: PropTypes.string,
  description: PropTypes.string,
  extraContent: PropTypes.node,
  actions: PropTypes.node,
};

function MfaCode({ title = '', mfaCode = 0 }) {
  return (
    <Box
      className="status-mfa"
      sx={{
        display: 'flex',
        flexDirection: 'column',
        justifyContent: 'center',
        alignItems: 'center',
        border: '1px solid',
        borderColor: 'grey.200',
        borderRadius: 1,
        maxWidth: '360px',
        backgroundColor: 'transparent',
        p: 1,
      }}>
      <Box
        className="status-mfa-tip"
        sx={{
          textAlign: 'center',
          textWrap: 'balance',
        }}>
        {title}
      </Box>
      <Typography
        className="status-mfa-code"
        sx={{
          mt: 1,
          lineHeight: 1,
          fontSize: '36px',
          fontWeight: 700,
          letterSpacing: 1,
        }}>
        {mfaCode}
      </Typography>
    </Box>
  );
}
MfaCode.propTypes = {
  title: PropTypes.string,
  mfaCode: PropTypes.number,
};

/**
 * Status (scanned/succeed/error/busy)
 */
export default function ConnectStatus({
  status = '',
  nextWorkflow = '',
  mfaCode = 0,
  onCancel = noop,
  onRetry = noop,
  onClose = noop,
  messages,
  locale = 'en',
  isFullScreen = false,
  loadingIcon = null,
  chooseMethod = 'DID Wallet',
  hideRetry = false,
  hideBack = false,
  ...rest
}) {
  const t = useMemoizedFn((key, data = {}) => {
    return translate(translations, key, locale, 'en', data);
  });
  const { palette } = useTheme();
  const closeButton = (
    <ActionButton sx={{ color: 'text.secondary' }} onClick={onClose}>
      {t('close')}
    </ActionButton>
  );

  return (
    <Box
      {...rest}
      sx={{
        p: 2,
        minHeight: 200,
        ...rest.sx,
      }}>
      {status === 'scanned' && !nextWorkflow && (
        <BaseStatus
          icon={
            <LoadingMask size={52} borderRadius={12}>
              {loadingIcon || <ProviderIcon provider={LOGIN_PROVIDER.DID_WALLET} width="100%" height="100%" />}
            </LoadingMask>
          }
          title={t('requestConnect')}
          description={t('continueInWallet', { method: chooseMethod })}
          extraContent={mfaCode > 0 && <MfaCode mfaCode={mfaCode} title={t('mfaCode')} />}
          actions={hideBack ? closeButton : <BackButton onClick={onCancel} />}
        />
      )}
      {status === 'scanned' && !!nextWorkflow && (
        <BaseStatus
          color={palette.secondary.main}
          icon={hourglassEmptyRoundedIcon}
          title={t('wait')}
          description={t('waiting')}
          extraContent={mfaCode > 0 && <MfaCode mfaCode={mfaCode} title={t('mfaCode')} />}
          actions={hideBack ? closeButton : <BackButton onClick={onCancel} />}
        />
      )}
      {status === 'succeed' && (
        <BaseStatus
          color="success.light"
          icon={<Success size={52} borderWidth={3} />}
          title={t('success')}
          description={messages.success}
          actions={isFullScreen ? null : closeButton}
        />
      )}
      {status === 'error' && (
        <BaseStatus
          color={palette.error.main}
          icon={closeRoundedIcon}
          title={t('failed')}
          description={messages.error || t('error')}
          actions={
            <Box sx={{ display: 'flex', gap: 1 }}>
              {hideBack ? closeButton : <BackButton onClick={onCancel} />}
              {hideRetry ? null : (
                <ActionButton
                  onClick={onRetry}
                  sx={{
                    color: 'primary.main',
                    borderColor: 'primary.light',
                  }}>
                  {t('retry')}
                </ActionButton>
              )}
            </Box>
          }
        />
      )}
      {status === 'busy' && (
        <BaseStatus
          color="warning.main"
          icon={ruleSettingsRoundedIcon}
          title={t('busyTitle')}
          description={messages.error || t('busyDesc')}
          actions={hideBack ? closeButton : <BackButton onClick={onCancel} />}
        />
      )}
    </Box>
  );
}

ConnectStatus.propTypes = {
  status: PropTypes.string,
  nextWorkflow: PropTypes.string,
  mfaCode: PropTypes.number,
  onCancel: PropTypes.func,
  onRetry: PropTypes.func,
  onClose: PropTypes.func,
  messages: PropTypes.shape({
    confirm: PropTypes.string.isRequired,
    success: PropTypes.any.isRequired,
    error: PropTypes.any.isRequired,
  }).isRequired,
  locale: PropTypes.oneOf(['en', 'zh']),
  isFullScreen: PropTypes.bool,
  loadingIcon: PropTypes.any,
  chooseMethod: PropTypes.string,
  hideRetry: PropTypes.bool,
  hideBack: PropTypes.bool,
};
