import { type FC, memo, type SyntheticEvent, useRef } from 'react';

import { useModal } from '@material-hu/hooks/useModal';
import {
  IconBell,
  IconBellOff,
  IconMessageCircle,
  IconPin,
  IconPinnedOff,
} from '@material-hu/icons/tabler';
import Box from '@material-hu/mui/Box';
import { Typography } from '@material-hu/mui/index';
import Stack from '@material-hu/mui/Stack';
import { useTheme } from '@material-hu/mui/styles';

import HuMenu from '@material-hu/components/design-system/Menu';
import HuMenuItem from '@material-hu/components/design-system/Menu/components/MenuItem';

import { logEvent } from 'src/config/amplitude';
import { useAuth } from 'src/contexts/JWTContext';
import useFeatureFlag from 'src/hooks/useFeatureFlag';
import IconMessageUnread from 'src/icons/MessageUnread';
import {
  CONVERSATIONS_LIST_CONTAINER,
  CONVERSATIONS_MESSAGES_CONTAINER,
  CONVERSATIONS_SIDEBAR_SCROLLBAR,
  MAX_PINNED_CONVERSATIONS,
} from 'src/pages/dashboard/Conversations/constants';
import {
  AmplitudeConversationType,
  type Channel,
  NotificationType,
} from 'src/pages/dashboard/Conversations/types';
import {
  buildOptions,
  getTimeFromOption,
} from 'src/pages/dashboard/Conversations/utils';
import { EventName } from 'src/types/amplitude';
import { FeatureFlags } from 'src/types/featureFlags';
import { useLokaliseTranslation } from 'src/utils/i18n';

import {
  useEditConversationProperties,
  useMarkMessages,
} from '../../hooks/useConversationsQueries';
import { useDisableScroll } from '../../hooks/useDisableScroll';
import { updateMarkedUnreadTs } from '../../queries';
import MuteMessageOption from '../shared/TimerModal';

import LimitPinnedConversations from './menuOptions/LimitPinnedConversations';

type ConversationItemIconMenuProps = {
  conversation: Channel;
  conversationId?: string;
  open: boolean;
  pinnedConversationsCount: number;
  onCloseMenu: () => void;
  onCloseMenuOnLeave: () => void;
};

const SIZE_ICON = 24;

const ConversationItemIconMenu: FC<ConversationItemIconMenuProps> = props => {
  const {
    open,
    conversation,
    conversationId,
    pinnedConversationsCount,
    onCloseMenu,
    onCloseMenuOnLeave,
  } = props;
  const buttonRef = useRef<HTMLButtonElement>(null);
  const { t } = useLokaliseTranslation('chat');
  const editConversationProperties = useEditConversationProperties();
  const markMessagesAsRead = useMarkMessages();

  const { user: loggedUser } = useAuth();
  const theme = useTheme();

  const isEnableMarkUnread = useFeatureFlag(FeatureFlags.CHATS_V2_MARK_UNREAD);

  const handleCloseModal = (e: SyntheticEvent) => {
    e.stopPropagation();
    closeLimitPinnedModal();
    closeMuteModal();
    onCloseMenuOnLeave();
  };

  useDisableScroll({
    isDisabled: open,
    containerId: CONVERSATIONS_LIST_CONTAINER,
    diabledPointerEvents: false,
  });

  useDisableScroll({
    isDisabled: open,
    containerId: CONVERSATIONS_MESSAGES_CONTAINER,
    diabledPointerEvents: false,
  });

  useDisableScroll({
    isDisabled: open,
    containerId: CONVERSATIONS_SIDEBAR_SCROLLBAR,
    diabledPointerEvents: false,
    capture: true,
  });

  const handleOnClose = (event: SyntheticEvent, reason: string) => {
    if (reason === 'backdropClick') {
      handleCloseModal(event);
      return;
    }
    handleCloseModal(event);
  };

  const {
    modal: muteModal,
    showModal: showMuteModal,
    closeModal: closeMuteModal,
  } = useModal(
    MuteMessageOption,
    {
      fullWidth: true,
      maxWidth: 'sm',
      onClose: handleOnClose,
    },
    {
      title: t('mute.dialog.title'),
      description: t('mute.dialog.description'),
      options: buildOptions(t, 'mute'),
      onClose: () => closeMuteModal(),
      onSubmit: (option: string) => {
        if (!conversation) return;
        logEvent(EventName.CHATS_2_CONVERSATION_MUTED, {
          userId: loggedUser?.id,
          conversationType: isGroupConversation
            ? AmplitudeConversationType.GROUP
            : AmplitudeConversationType.INDIVIDUAL,
          conversationId,
          duration: option,
        });
        editConversationProperties.mutate({
          channel: conversation.id,
          properties: {
            notification_status: {
              notification_type: NotificationType.MENTIONS,
              until: getTimeFromOption(option),
            },
            pinned_at: conversation.properties.pinned_at,
            marked_unread_at: conversation.properties.marked_unread_at,
          },
        });
      },
      isLoading: editConversationProperties.isLoading,
      primaryButtonLabel: t('mute.mute'),
    },
  );

  const {
    modal: limitPinnedModal,
    showModal: showLimitPinnedModal,
    closeModal: closeLimitPinnedModal,
  } = useModal(LimitPinnedConversations, {
    fullWidth: true,
    maxWidth: 'sm',
    onClose: handleOnClose,
  });

  const isGroupConversation = conversation?.is_channel || false;
  const isMentionConversation =
    conversation.properties?.notification_status?.notification_type ===
    NotificationType.MENTIONS;
  const isPinnedConversation = !!conversation.properties?.pinned_at;
  const hasUnread =
    conversation.unread_count_display > 0 ||
    !!conversation.properties.marked_unread_at;
  const menuOptions = [
    {
      id: 'mute_conversation',
      enabled: true,
      label: isMentionConversation ? t('mute.unmute') : t('mute.mute'),
      icon: isMentionConversation ? (
        <IconBell
          size={SIZE_ICON}
          color={theme.palette.new.text.neutral.default}
        />
      ) : (
        <IconBellOff
          size={SIZE_ICON}
          color={theme.palette.new.text.neutral.default}
        />
      ),
      onClick: (e: SyntheticEvent) => {
        e.stopPropagation();
        if (isMentionConversation) {
          logEvent(EventName.CHATS_2_CONVERSATION_UNMUTED, {
            userId: loggedUser?.id,
            conversationType: isGroupConversation
              ? AmplitudeConversationType.GROUP
              : AmplitudeConversationType.INDIVIDUAL,
            conversationId,
          });
          editConversationProperties.mutate({
            channel: conversationId || '',
            properties: {
              notification_status: {
                notification_type: NotificationType.ALL,
                until: null,
              },
              pinned_at: conversation.properties.pinned_at,
              marked_unread_at: conversation.properties.marked_unread_at,
            },
          });
        } else {
          showMuteModal();
        }
        onCloseMenu();
      },
    },
    {
      id: 'pin_conversation',
      enabled: true,
      label: isPinnedConversation ? t('pin.unpin') : t('pin.pin'),
      icon: isPinnedConversation ? (
        <IconPinnedOff
          size={SIZE_ICON}
          color={theme.palette.new.text.neutral.default}
        />
      ) : (
        <IconPin
          size={SIZE_ICON}
          color={theme.palette.new.text.neutral.default}
        />
      ),
      onClick: (e: SyntheticEvent) => {
        e.stopPropagation();
        if (
          pinnedConversationsCount >= MAX_PINNED_CONVERSATIONS &&
          !isPinnedConversation
        ) {
          showLimitPinnedModal();
          onCloseMenu();
          return;
        }

        logEvent(
          isPinnedConversation
            ? EventName.CHATS_2_CONVERSATION_UNPINNED
            : EventName.CHATS_2_CONVERSATION_PINNED,
          {
            userId: loggedUser?.id,
            conversationType: isGroupConversation
              ? AmplitudeConversationType.GROUP
              : AmplitudeConversationType.INDIVIDUAL,
            conversationId,
          },
        );

        editConversationProperties.mutate({
          channel: conversationId || '',
          properties: {
            notification_status: conversation.properties.notification_status,
            pinned_at: isPinnedConversation ? null : Date.now(),
            marked_unread_at: conversation.properties.marked_unread_at,
          },
        });
        onCloseMenu();
      },
    },
    {
      id: 'mark_read_unread_conversation',
      enabled: isEnableMarkUnread,
      label: hasUnread ? t('mark.mark_read') : t('mark.mark_unread'),
      icon: hasUnread ? (
        <IconMessageCircle
          size={SIZE_ICON}
          color={theme.palette.new.text.neutral.default}
        />
      ) : (
        <IconMessageUnread />
      ),
      onClick: (e: SyntheticEvent) => {
        e.stopPropagation();
        if (!conversationId) return;
        if (hasUnread) {
          markMessagesAsRead.mutate(
            {
              channelId: conversationId,
              markedUnreadTs: conversation?.latest?.ts,
            },
            {
              onSuccess: (_, { channelId, markedUnreadTs }) => {
                updateMarkedUnreadTs({ channelId, markedUnreadTs });
              },
            },
          );
        } else {
          editConversationProperties.mutate({
            channel: conversationId || '',
            properties: {
              notification_status: conversation.properties.notification_status,
              pinned_at: conversation.properties.pinned_at,
              marked_unread_at: Date.now(),
            },
          });
        }
        logEvent(
          hasUnread
            ? EventName.CHATS_2_CONVERSATION_MARKED_READ
            : EventName.CHATS_2_CONVERSATION_MARKED_UNREAD,
          {
            conversationId,
          },
        );

        onCloseMenu();
      },
    },
  ];

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

  return (
    <Stack>
      {muteModal}
      {limitPinnedModal}
      <Box ref={buttonRef} />
      <HuMenu
        open={open}
        onClose={onCloseMenu}
        anchorEl={buttonRef.current}
        position="right"
        sx={{
          '& .MuiPaper-root': { mt: -4, ml: 10 },
          '& .MuiMenuItem-root:first-of-type, & .MuiMenuItem-root:last-of-type':
            {
              height: '51px',
            },
        }}
      >
        {filteredOptions.map(({ id, onClick, label, icon }) => (
          <HuMenuItem
            key={id}
            onClick={onClick}
            sx={{
              minWidth: '236px',
              height: '40px',
              display: 'flex',
              justifyContent: 'space-between',
            }}
          >
            <Typography
              variant="globalXS"
              fontWeight="fontWeightSemiBold"
              color={theme.palette.new.text.neutral.default}
            >
              {label}
            </Typography>
            {icon}
          </HuMenuItem>
        ))}
      </HuMenu>
    </Stack>
  );
};

export default memo(ConversationItemIconMenu);
