import { Icon } from '@iconify/react';
import { Box, Tooltip, Typography } from '@mui/material';
import LinkRoundedIcon from '@iconify-icons/material-symbols/link-rounded';
import Button from '@arcblock/ux/lib/Button';
import Avatar from '@arcblock/ux/lib/Avatar';
import { useCreation, useMemoizedFn, useReactive } from 'ahooks';
import { translate } from '@arcblock/ux/lib/Locale/util';
import { useConfirm } from '@arcblock/ux/lib/Dialog';
import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
import MailOutlineRoundedIcon from '@iconify-icons/material-symbols/mail-outline-rounded';
import InfoOutlineRoundedIcon from '@iconify-icons/material-symbols/info-outline-rounded';
import PasskeyIcon from '@iconify-icons/material-symbols/passkey';
import WalletIcon from '@iconify-icons/material-symbols/wallet-sharp';
import AppleIcon from '@iconify-icons/logos/apple';
import GithubIcon from '@iconify-icons/logos/github-icon';
import GoogleIcon from '@iconify-icons/logos/google-icon';
// import Auth0Icon from '@iconify-icons/logos/auth0-icon';
import { SessionContext } from '@arcblock/did-connect-react/lib/Session';
import { use } from 'react';
import pick from 'lodash/pick';
import { getFederatedEnabled, getMaster } from '@arcblock/ux/lib/Util/federated';
import { LOGIN_PROVIDER, LOGIN_PROVIDER_NAME, OAUTH_PROVIDER } from '@arcblock/ux/lib/Util/constant';
import { useStateContext } from '@arcblock/did-connect-react/lib/Connect/contexts/state';

import { translations } from '../../libs/locales';
import type { OAuthAccount, SessionContext as TSessionContext } from '../../../@types';

export default function ThirdPartyItem({
  item,
}: {
  item: {
    provider: string;
    did: string;
    pk: string;
    userInfo?: OAuthAccount['userInfo'];
    id: string;
    _bind?: boolean;
    _rawProvider?: string;
    _mainProvider?: boolean;
  };
}) {
  const { blocklet: targetBlocklet } = useStateContext();
  const { confirmApi, confirmHolder } = useConfirm();
  const currentState = useReactive({
    loading: false,
  });
  const { locale } = useLocaleContext();
  const t = useMemoizedFn((key, data = {}) => {
    return translate(translations, key, locale, 'en', data);
  });
  const { session } = use<TSessionContext>(SessionContext);
  const { bindOAuth, unbindOAuth, setBaseUrl, baseUrl: oauthBaseUrl } = session.useOAuth();
  const { disconnectPasskey, setTargetAppPid } = session.usePasskey();

  const iconMap = {
    // email: MailOutlineRoundedIcon,
    [LOGIN_PROVIDER.AUTH0]: MailOutlineRoundedIcon,
    [LOGIN_PROVIDER.APPLE]: AppleIcon,
    [LOGIN_PROVIDER.GITHUB]: GithubIcon,
    [LOGIN_PROVIDER.GOOGLE]: GoogleIcon,
    [LOGIN_PROVIDER.PASSKEY]: PasskeyIcon,
    [LOGIN_PROVIDER.WALLET]: WalletIcon,
  };

  const icon = useCreation(() => {
    return iconMap[item?.provider];
  }, [item?.provider]);
  const title = useCreation(() => {
    return LOGIN_PROVIDER_NAME[item?.provider as keyof typeof OAUTH_PROVIDER] || 'unknown';
  }, [item?.provider]);

  const toggleBind = useMemoizedFn(async () => {
    if (item?.provider === LOGIN_PROVIDER.PASSKEY) {
      await new Promise((resolve, reject) => {
        confirmApi.open({
          title: t('thirdPartyLogin.disconnectPasskey', { name: title }),
          content: t('thirdPartyLogin.disconnectPasskeyDescription', { name: title }),
          confirmButtonText: t('common.confirm'),
          confirmButtonProps: {
            color: 'error',
          },
          cancelButtonText: t('common.cancel'),
          onConfirm(close: () => void) {
            disconnectPasskey({ session, connectedAccount: item }).then(resolve).catch(reject);
            close();
          },
          // @ts-ignore
          onCancel: resolve,
        });
      });
      return;
    }

    try {
      currentState.loading = true;
      await new Promise((resolve, reject) => {
        if (item?._bind) {
          confirmApi.open({
            title: t('thirdPartyLogin.confirmUnbind', { name: title }),
            content: t('thirdPartyLogin.confirmUnbindDescription', { name: title }),
            confirmButtonText: t('common.confirm'),
            confirmButtonProps: {
              color: 'error',
            },
            cancelButtonText: t('common.cancel'),
            onConfirm(close: () => void) {
              unbindOAuth({
                session,
                connectedAccount: {
                  ...pick(item, ['did', 'pk']),
                  showProvider: item.provider,
                  provider: item._rawProvider,
                },
              })
                .then(resolve)
                .catch(reject);
              close();
            },
            // @ts-ignore
            onCancel: resolve,
          });
        } else {
          const backupBaseUrl = oauthBaseUrl;
          const blocklet = window?.blocklet;
          let baseUrl = '/';
          const federatedEnabled = getFederatedEnabled(blocklet);
          const master = getMaster(blocklet);
          if (federatedEnabled && master?.appPid && session?.user?.sourceAppPid) {
            baseUrl = master.appUrl;
          }
          setBaseUrl(baseUrl);
          // @ts-ignore
          setTargetAppPid(targetBlocklet?.appPid);
          bindOAuth({
            session,
            oauthItem: {
              ...item,
              provider: item._rawProvider,
            },
          })
            .then(resolve)
            .catch(reject)
            .finally(() => {
              setBaseUrl(backupBaseUrl);
              setTargetAppPid();
            });
        }
      });
    } catch (err) {
      console.error(`Failed to ${item?._bind ? 'unbind' : 'bind'} oauth account`, err);
    } finally {
      currentState.loading = false;
    }
  });

  return (
    <>
      <Box
        sx={{
          borderRadius: 1,
          border: '1px solid',
          borderColor: 'divider',
          backgroundColor: 'grey.50',
          display: 'flex',
          alignItems: 'center',
          py: 1,
          px: 1.5,
          gap: 0.75,
          fontSize: '14px',
          lineHeight: 1,
          overflow: 'hidden',
        }}>
        <Box
          component={Icon}
          icon={icon}
          fill="currentColor"
          sx={{
            width: '1em',
            height: '1em',
            flexShrink: 0,
            fontSize: 16,

            // githubIcon 不支持变色，dark 模式做一个反色处理
            filter: ({ palette }) =>
              item?.provider === LOGIN_PROVIDER.GITHUB && palette.mode === 'dark' ? 'invert(1)' : 'none',
          }}
        />
        <Box
          sx={{
            flex: 1,
          }}>
          {title}
        </Box>
        <Box
          sx={{
            display: 'flex',
            alignItems: 'center',
            gap: 0.5,
          }}>
          <Box
            sx={{
              flex: 1,
              textOverflow: 'ellipsis',
              overflow: 'hidden',
              lineHeight: 'normal',
            }}>
            {item.userInfo?.email || item.did}
          </Box>
          {item.userInfo?.name ? (
            <Tooltip
              title={
                <>
                  <Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
                    <Avatar size={36} variant="circle" shape="circle" src={item.userInfo?.picture} did={item.did} />
                    <Box>
                      <Typography
                        sx={{
                          whiteSpace: 'normal',
                          wordBreak: 'break-all',
                          fontSize: '0.9rem',
                        }}>
                        {item.userInfo?.name}
                      </Typography>
                      <Typography
                        sx={{
                          whiteSpace: 'normal',
                          wordBreak: 'break-all',
                          fontSize: '0.9rem',
                        }}>
                        {item.userInfo?.email}
                      </Typography>
                    </Box>
                  </Box>
                  {/* 暂不显示 oauth 账户的 did */}
                  {/* <Box
                    component={DID}
                    did={item.did}
                    sx={{
                      '& .did-address-text': {
                        color: 'white',
                      },
                    }}
                  /> */}
                </>
              }>
              <Box
                component={Icon}
                icon={InfoOutlineRoundedIcon}
                sx={{
                  color: 'text.secondary',
                  fontSize: 16,
                  cursor: 'pointer',
                  flexShrink: 0,
                }}
              />
            </Tooltip>
          ) : null}
        </Box>
      </Box>
      <Tooltip title={item._mainProvider ? t('thirdPartyLogin.mainProviderCantRemove') : ''}>
        {/* HACK: 结合下面的 button disable 使用，必须增加这一层 */}
        <Box>
          <Button
            variant="outlined"
            size="small"
            sx={(theme) => {
              const textRed = theme.palette.error.main;
              const textPrimary = theme.palette.primary.main;

              return {
                color: item?._bind ? textRed : textPrimary,
                borderColor: item?._bind ? textRed : textPrimary,
                backgroundColor: 'background.default',
                '&:hover': {
                  borderColor: item?._bind ? textRed : textPrimary,
                  backgroundColor: 'action.hover',
                },
                py: 0.5,
                borderRadius: 1,
                fontWeight: 500,
                whiteSpace: 'nowrap',
              };
            }}
            fullWidth
            startIcon={currentState.loading ? null : <Icon icon={LinkRoundedIcon} />}
            onClick={toggleBind}
            disabled={item._mainProvider}
            loading={currentState.loading}>
            {item?._bind ? t('thirdPartyLogin.disconnect') : t('thirdPartyLogin.connect')}
          </Button>
        </Box>
      </Tooltip>
      {confirmHolder}
    </>
  );
}
