import {
  Box,
  ClickAwayListener,
  Divider,
  Fade,
  LinearProgress,
  MenuItem,
  MenuList,
  Paper,
  Popper,
  useTheme,
} from '@mui/material';
import { useRef } from 'react';
import { useCreation, useMemoizedFn, useReactive, useSize, useMount } from 'ahooks';
import { Icon } from '@iconify/react';
import AddCircleOutlineRoundedIcon from '@iconify-icons/material-symbols/add-circle-outline-rounded';
import ExpandMoreRoundedIcon from '@iconify-icons/material-symbols/expand-more-rounded';
import SwapHorizRoundedIcon from '@iconify-icons/material-symbols/swap-horiz-rounded';
import pick from 'lodash/pick';

import SessionUserItem from './session-user-item';
import { getVisitorId } from '../../Util';
import { translate } from '../../Locale/util';
import { translations } from '../libs/translation';
import type { Locale, Session } from '../../type';

export interface SessionUserSwitchProps {
  session: Session;
  onSwitch: (params?: { userSession: Session }) => Promise<void> | void;
  isBlocklet?: true | false;
  locale?: Locale;
}

export default function SessionUserSwitch({
  session,
  onSwitch,
  isBlocklet = true,
  locale = 'en',
}: SessionUserSwitchProps) {
  const popperAnchorRef = useRef(null);
  const { palette } = useTheme();
  const t = useMemoizedFn((key, data = {}) => {
    return translate(translations, key, locale, 'en', data);
  });

  const currentState = useReactive({
    open: false,
    userSessions: [] as Session[],
    loadingSessionId: null,
  });

  useMount(async () => {
    if (isBlocklet) {
      const userSessions = await session.getUserSessions();
      currentState.userSessions = userSessions;
    }
  });

  const currentSession = useCreation(() => {
    const matchSession = (currentState.userSessions || []).find(
      (item) => item.appPid === globalThis?.blocklet?.appPid && item.userDid === session?.user?.did
    );
    if (matchSession) {
      return matchSession;
    }

    return {
      __isDefault: true,
      appName: globalThis?.blocklet?.appName || globalThis?.env?.appName,
      appPid: globalThis?.blocklet?.appPid || globalThis?.env?.appPid,
      userDid: session?.user?.did,
      visitorId: getVisitorId(),
      // passportId: '', // 无法从当前 session 获取 passportId 的值
      // updatedAt: '', // 当前 session 拼凑的信息无法得到 userSession 的更新时间
      user: pick(session?.user, [
        'did',
        'sourceProvider',
        'fullName',
        'email',
        'avatar',
        'remark',
        'sourceAppPid',
        'role',
      ]),
    };
  }, [currentState.userSessions, session?.user]);
  const onTogglePopper = useMemoizedFn((value = !currentState.open) => {
    currentState.open = value;
  });
  const size = useSize(popperAnchorRef.current);
  const handleAddAccount = useMemoizedFn(() => {
    onTogglePopper(false);
    onSwitch();
  });
  const handleSwitch = useMemoizedFn(async (userSession) => {
    try {
      currentState.loadingSessionId = userSession?.id;
      await onSwitch({ userSession });
      onTogglePopper(false);
    } finally {
      currentState.loadingSessionId = null;
    }
  });

  if (!isBlocklet) {
    return (
      <SessionUserItem
        sessionItem={currentSession}
        statusContent={<Icon icon={SwapHorizRoundedIcon} color={palette.text.hint} />}
        sx={{
          borderRadius: 1,
          cursor: 'pointer',
          py: 1.25,
          px: 1.5,
        }}
        data-cy="sessionManager-switch-trigger"
        onClick={handleAddAccount}
        ref={popperAnchorRef}
      />
    );
  }
  return (
    <>
      <SessionUserItem
        sessionItem={currentSession}
        statusContent={
          <Box
            component={Icon}
            icon={ExpandMoreRoundedIcon}
            className="session-user-switch-icon"
            sx={{
              transform: 'scale(1.5) rotate(-90deg)',
              transition: 'transform 0.2s ease',
            }}
          />
        }
        sx={{
          borderRadius: 1,
          cursor: 'pointer',
          py: 1.25,
          px: 2,
          '&:hover': {
            backgroundColor: `${palette.grey[200]} !important`,
            '.session-user-switch-icon': {
              transform: 'scale(1.5)',
            },
          },
        }}
        onClick={() => onTogglePopper()}
        ref={popperAnchorRef}
      />
      <Popper open={currentState.open} anchorEl={popperAnchorRef.current} transition sx={{ zIndex: 1600 }}>
        {({ TransitionProps }) => (
          <ClickAwayListener
            onClickAway={(e) => {
              e.preventDefault();
              e.stopPropagation();
              onTogglePopper(false);
            }}>
            <Fade {...TransitionProps} timeout={350}>
              <Paper
                variant="outlined"
                sx={{
                  borderRadius: 3,
                  width: size?.width || 0,
                  borderColor: 'divider',
                  mt: 0.5,
                  border: '0 !important',
                  boxShadow: `0px 8px 16px 0px ${palette.grey[100]}, 0px 0px 0px 1px ${palette.grey[100]}`,
                }}>
                <MenuList sx={{ p: 0.5 }}>
                  {currentState.userSessions.map((userSessionItem) => {
                    const isLoading = currentState.loadingSessionId === userSessionItem.id;
                    const isActive = userSessionItem.id === currentSession.id;

                    return (
                      <MenuItem
                        key={userSessionItem.id}
                        sx={{
                          position: 'relative',
                          p: 0,
                          '&:hover': {
                            backgroundColor: `${palette.grey[200]} !important`,
                          },
                        }}
                        onClick={() => {
                          if (!isActive) {
                            handleSwitch(userSessionItem);
                          }
                        }}>
                        {isLoading && (
                          <LinearProgress
                            sx={{
                              height: '2px',
                              position: 'absolute',
                              top: 0,
                              left: 0,
                              right: 0,
                            }}
                          />
                        )}
                        <SessionUserItem sessionItem={userSessionItem} active={isActive} />
                      </MenuItem>
                    );
                  })}
                  {currentState.userSessions.length > 0 ? (
                    <Divider sx={{ m: '0!important', borderColor: 'divider' }} />
                  ) : null}
                  <MenuItem
                    sx={{
                      color: 'secondary.main',
                      borderRadius: 1,
                      '&:hover': {
                        backgroundColor: `${palette.grey[200]} !important`,
                      },
                      px: 1,
                      py: 1.5,
                      lineHeight: 1,
                    }}
                    onClick={handleAddAccount}
                    data-cy="sessionManager-switch-trigger">
                    <Box
                      component={Icon}
                      icon={AddCircleOutlineRoundedIcon}
                      sx={{
                        fontSize: 20,
                        mr: 0.5,
                      }}
                    />
                    {t('addAnotherAccount')}
                  </MenuItem>
                </MenuList>
              </Paper>
            </Fade>
          </ClickAwayListener>
        )}
      </Popper>
    </>
  );
}
