import { type FC, Fragment, useState } from 'react';

import MoreIcon from '@material-hu/icons/material/ExpandMore';
import Box from '@material-hu/mui/Box';
import IconButton from '@material-hu/mui/IconButton';
import Menu from '@material-hu/mui/Menu';
import { styled } from '@material-hu/mui/styles';

import { type MenuProps } from '@material-hu/components/design-system/Menu/types';

import { useAuth } from 'src/contexts/JWTContext';
import { type Attachment, FileTypes } from 'src/types/attachments';
import { type ChatType, MessageStatus, MessageType } from 'src/types/chats';
import { type User } from 'src/types/user';
import { canReply } from 'src/utils/chats';

import { useTranslation } from 'src/components/dashboard/chat/i18n';

import {
  DeleteMessageOption,
  DownloadAudioOption,
  DownloadImageOption,
  EditMessageOption,
  ForwardMessageOption,
  ReplyMessageOption,
} from './menuOptions';

const StyledMenu = styled(Menu)({
  '& .MuiPaper-root': {
    borderRadius: 6,
    minWidth: 180,
    boxShadow:
      '0px 1px 2px rgba(0, 0, 0, 0.12),0px 0px 0px 1px rgba(0, 0, 0, 0.05)',
    '& .MuiMenu-list': {
      padding: '4px 0',
    },
    '& .MuiMenuItem-root': {
      '& .MuiSvgIcon-root': {
        fontSize: 18,
      },
    },
  },
});

export type MessageMenuProps = Omit<
  MenuProps,
  'open' | 'anchorEl' | 'onClose'
> & {
  sender: User;
  messageId: string | number;
  chatId: number;
  attachment: Attachment;
  openInputToEditMessage: any;
  status?: MessageStatus;
  contentType: string;
  chatType: ChatType;
  onClose?: (event) => any;
  onOpenDialog?: () => void;
};

export const MessageMenu: FC<MessageMenuProps> = props => {
  const {
    sender,
    messageId,
    chatId,
    attachment,
    openInputToEditMessage,
    status,
    contentType,
    chatType,
    onClose = () => null,
    onOpenDialog,
    ...menuProps
  } = props;

  const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null);
  const open = Boolean(anchorEl);

  const { user } = useAuth();
  const { t } = useTranslation();

  const openMenu = event => {
    event.stopPropagation();
    setAnchorEl(event.currentTarget);
  };

  const closeMenu = event => {
    event.stopPropagation();
    onClose(event);
    setAnchorEl(null);
  };

  const wasDeleted = status === MessageStatus.DELETED;
  const wasForwarded = status === MessageStatus.FORWARDED;
  const isFile = contentType === MessageType.FILE;
  const isAudio = contentType === MessageType.AUDIO;
  const isLoggedUser = user.id === sender?.id;

  const menuOptions = [
    {
      id: 'forward_message',
      enabled: true,
      option: (
        <ForwardMessageOption
          closeMenu={closeMenu}
          messageId={messageId}
          chatId={chatId}
          onOpenDialog={onOpenDialog}
        />
      ),
    },
    {
      id: 'reply_message',
      enabled: canReply(contentType),
      option: (
        <ReplyMessageOption
          closeMenu={closeMenu}
          messageId={messageId}
          chatId={chatId}
          chatType={chatType}
        />
      ),
    },
    {
      id: 'delete_message',
      enabled: isLoggedUser,
      option: (
        <DeleteMessageOption
          closeMenu={closeMenu}
          messageId={messageId}
          chatId={chatId}
        />
      ),
    },
    {
      id: 'edit_message',
      enabled: isLoggedUser && !wasForwarded && !isFile && !isAudio,
      option: <EditMessageOption onClick={openInputToEditMessage} />,
    },
    {
      id: 'download_image',
      enabled: attachment?.type === FileTypes.IMAGE,
      option: (
        <DownloadImageOption
          closeMenu={closeMenu}
          attachment={attachment}
        />
      ),
    },
    {
      id: 'download_audio',
      enabled: attachment?.type === FileTypes.AUDIO,
      option: (
        <DownloadAudioOption
          closeMenu={closeMenu}
          attachment={attachment}
        />
      ),
    },
  ];

  const filteredOptions = menuOptions.filter(option => option.enabled);

  return (
    <Box>
      {!wasDeleted && (
        <IconButton
          size="small"
          id="message-menu-button"
          aria-controls="message-menu"
          aria-haspopup="true"
          aria-label={t('MESSAGE_MENU')}
          aria-expanded={open ? 'true' : undefined}
          onClick={openMenu}
        >
          <MoreIcon
            sx={{
              color: theme => theme.palette.common.white,
            }}
          />
        </IconButton>
      )}
      <StyledMenu
        {...menuProps}
        id="message-menu"
        elevation={0}
        anchorOrigin={{
          vertical: 'bottom',
          horizontal: 'right',
        }}
        transformOrigin={{
          vertical: 'top',
          horizontal: 'right',
        }}
        MenuListProps={{
          'aria-labelledby': 'message-menu-button',
        }}
        anchorEl={anchorEl}
        open={open}
        onClose={closeMenu}
      >
        <Box>
          {filteredOptions.map(({ id, option }) => (
            <Fragment key={id}>{option}</Fragment>
          ))}
        </Box>
      </StyledMenu>
    </Box>
  );
};

export default MessageMenu;
