import {
  Box,
  CircularProgress,
  Divider,
  Fade,
  IconButton,
  LinearProgress,
  MenuItem,
  MenuList,
  Paper,
  Popper,
  useTheme,
} from '@mui/material';
import { Icon } from '@iconify/react';
import UserIcon from '@iconify-icons/tabler/user';
import { Fragment, useEffect, useRef } from 'react';
import { useMemoizedFn, useReactive } from 'ahooks';
import noop from 'lodash/noop';
import DidBrandLogo from '@arcblock/icons/lib/DidBrandLogo';
import { useBrowser } from '@arcblock/react-hooks';
import { joinURL } from 'ufo';

import { Session } from '../../type';
import CloseButton from '../../CloseButton';
import { translate } from '../../Locale/util';
import { translations } from '../libs/translation';
import Typography from '../../Typography';
import QuickLoginItem from './quick-login-item';
import { getFederatedEnabled, getMaster } from '../../Util/federated';
import { BLOCKLET_SERVICE_PATH_PREFIX } from '../../Util/constant';

export interface UnLoginProps {
  session: Session;
  onLogin?: () => void;
  size?: number;
  dark?: false | true;
  locale?: string;
}

export default function UnLogin({ session, onLogin = noop, size = 24, dark = false, locale = 'en' }: UnLoginProps) {
  const { palette } = useTheme();
  const t = useMemoizedFn((key, data = {}) => {
    return translate(translations, key, locale, 'en', data);
  });
  const searchParams = new URLSearchParams(window.location.search);
  const browser = useBrowser();
  const isFirstLoading = false;
  const userAnchorRef = useRef(null);
  const currentState = useReactive({
    open: false,
    userSessions: [] as Session[],
    loadingSessionId: null,
    loadAppLogoError: false,
  });
  const onTogglePopper = useMemoizedFn((value = !currentState.open) => {
    currentState.open = value;
  });

  const _onLogin = useMemoizedFn(({ openMode } = {}) => {
    if (isFirstLoading) {
      return;
    }
    session.login(onLogin, { openMode });
  });

  const blocklet = window?.blocklet;
  const federatedEnabled = getFederatedEnabled(blocklet);
  const masterSite = getMaster(blocklet);
  const loginApp = federatedEnabled && masterSite ? masterSite : blocklet;
  const loginAppName = loginApp?.appName || 'DID Connect';
  const loginAppLogo = joinURL(
    loginApp?.appUrl || '/',
    loginApp?.appLogo || `${BLOCKLET_SERVICE_PATH_PREFIX}/blocklet/logo?imageFilter=convert&f=png&h=80`
  );

  useEffect(() => {
    let timer: NodeJS.Timeout;

    // NOTICE: ArcSphere 中使用原生的快捷登录
    if (!browser.arcSphere && searchParams.get('showQuickConnect') !== 'false') {
      timer = setTimeout(async () => {
        currentState.userSessions = await session.getUserSessions();
        if (currentState.userSessions.length > 0) {
          currentState.open = true;
        }
      }, 1500);
    }

    return () => {
      clearTimeout(timer);
    };
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  const handleLogin = useMemoizedFn(async (userSession) => {
    currentState.loadingSessionId = userSession.id;
    try {
      await session.loginUserSession({ ...userSession, appPid: blocklet?.appPid });
    } catch (err) {
      console.error('session.loginUserSession.error', err);
    } finally {
      currentState.loadingSessionId = null;
    }
  });

  return (
    <>
      <IconButton
        ref={userAnchorRef}
        data-cy="sessionManager-login"
        className="arc-session-user-unlogin"
        size="medium"
        onClick={_onLogin}
        aria-label="Login button">
        {isFirstLoading ? (
          <Box
            sx={{
              width: size,
              height: size,
              display: 'flex',
              justifyContent: 'center',
              alignItems: 'center',
            }}>
            <CircularProgress style={{ width: size - 4, height: size - 4, color: dark ? '#fff' : '' }} />
          </Box>
        ) : (
          <Icon
            icon={UserIcon}
            fontSize={size}
            color={dark ? '#fff' : 'inherit'}
            style={{ transform: 'scale(1.25)' }}
          />
        )}
      </IconButton>
      <Popper
        open={currentState.open}
        anchorEl={userAnchorRef.current}
        transition
        sx={{
          zIndex: (theme) => theme.zIndex.appBar,
        }}
        placement="bottom-end"
        modifiers={[
          {
            name: 'offset',
            options: {
              offset: [0, 10], // [水平偏移, 垂直偏移]
            },
          },
        ]}>
        {({ TransitionProps }) => (
          <Fade {...TransitionProps}>
            <Paper
              variant="outlined"
              sx={{
                borderRadius: 1,
                width: 400,
                maxWidth: '90vw',
                borderColor: 'divider',
                border: '0 !important',
                boxShadow: 4,
                overflow: 'hidden',
              }}>
              <Box
                sx={{
                  display: 'flex',
                  alignItems: 'center',
                  gap: 1,
                  p: 2,
                  borderBottom: '1px solid',
                  borderColor: 'divider',
                }}>
                {loginAppLogo && !currentState.loadAppLogoError ? (
                  <img
                    src={loginAppLogo}
                    style={{
                      height: 20,
                      maxWidth: 100,
                    }}
                    onError={() => {
                      currentState.loadAppLogoError = true;
                    }}
                    alt="Login App Logo"
                  />
                ) : (
                  <DidBrandLogo height={24} width={24} />
                )}
                <Typography
                  fontSize="auto"
                  sx={{
                    fontSize: '16',
                    flex: 1,
                    color: 'text.secondary',
                    // 最多展示三行
                    overflow: 'hidden',
                    textOverflow: 'ellipsis',
                    display: '-webkit-box',
                    WebkitLineClamp: 3,
                    WebkitBoxOrient: 'vertical',
                  }}>
                  {t('useQuickLogin', { name: loginAppName })}
                </Typography>
                <CloseButton onClose={() => onTogglePopper(false)} />
              </Box>
              <MenuList sx={{ p: 0, overflow: 'hidden' }}>
                {currentState.userSessions.map((userSessionItem, index) => {
                  const isLoading = currentState.loadingSessionId === userSessionItem.id;

                  return (
                    <Fragment key={`${userSessionItem.id}-root`}>
                      <MenuItem
                        key={userSessionItem.id}
                        sx={{
                          overflow: 'hidden',
                          position: 'relative',
                          p: 0,
                          bgcolor: 'background.paper',
                          '&:hover': {
                            bgcolor: `${palette.action.hover} !important`,
                          },
                        }}
                        onClick={() => {
                          handleLogin(userSessionItem);
                        }}>
                        {isLoading && (
                          <LinearProgress
                            sx={{
                              height: '2px',
                              position: 'absolute',
                              top: 0,
                              left: 0,
                              right: 0,
                            }}
                          />
                        )}
                        <QuickLoginItem userSession={userSessionItem as unknown as any} locale={locale} />
                      </MenuItem>
                      {index < currentState.userSessions.length - 1 ? (
                        <Divider
                          key={`${userSessionItem.id}-divider`}
                          sx={{
                            mx: 2,
                            my: '0px !important',
                          }}
                        />
                      ) : null}
                    </Fragment>
                  );
                })}
              </MenuList>
            </Paper>
          </Fade>
        )}
      </Popper>
    </>
  );
}
