import { useCallback, useMemo, useRef, useState } from 'react';

import {
  IconCopy,
  IconEdit,
  IconInfoCircle,
  IconMoodSmile,
  IconPinned,
  IconPinnedOff,
  IconShare3,
  IconTrash,
} from '@material-hu/icons/tabler';

import { useDialogLayer } from '@material-hu/components/layers/Dialogs';

import { logEvent } from 'src/config/logging';
import useFeatureFlag from 'src/hooks/useFeatureFlag';
import {
  CONVERSATION_TYPE,
  MAX_EMOJIS_LIMIT,
  MESSAGE_DELETE_DIALOG_ID,
  MESSAGE_EDIT_DIALOG_ID,
  MESSAGE_FORWARD_DIALOG_ID,
  MESSAGE_PIN_DIALOG_ID,
} from 'src/pages/dashboard/Conversations/constants';
import {
  type ConversationMessage,
  type Member,
  StateMessage,
  type SummaryReaction,
} from 'src/pages/dashboard/Conversations/types';
import {
  buildOptions,
  getMessageContentType,
  getTimeFromOption,
  getTypeMessage,
} from 'src/pages/dashboard/Conversations/utils';
import { EventName } from 'src/types/amplitude';
import { FileTypes } from 'src/types/attachments';
import { FeatureFlags } from 'src/types/featureFlags';
import { useLokaliseTranslation } from 'src/utils/i18n';

import PinnedMessageModal from '../components/ConversationsThread/ConversationThreadToolbar/PinnedMessages/PinnedMessageModal';
import MessageDelete from '../components/MessageSetting/MessageDelete';
import MessageEdit, {
  type MessageEditHandle,
} from '../components/MessageSetting/MessageEdit';
import MessageForward from '../components/MessageSetting/MessageForward';
import { useReplayMessageSetter } from '../contexts/ReplayMessageConversationContext';
import { useSearchHighlight } from '../contexts/SearchHighlightContext';

import { useUpdatePinnedMessages } from './useConversationsQueries';
import { useMessageCopy } from './useMessageCopy';

type UseSettingMenuParams = {
  message: ConversationMessage;
  isLoggedUser: boolean;
  reactions: SummaryReaction[];
  members: Member[];
  isMessageForwarded?: boolean;
  isGroupConversation?: boolean;
  isPinnedMessage: boolean;
  pinnedMessagesCount: number;
  onReactClick: () => void;
  onCloseMenu: () => void;
};

export const useSettingMenu = ({
  message,
  isLoggedUser,
  reactions,
  members,
  isMessageForwarded,
  isGroupConversation,
  isPinnedMessage,
  pinnedMessagesCount,
  onReactClick,
  onCloseMenu,
}: UseSettingMenuParams) => {
  const [openMenuMessageInfo, setOpenMenuMessageInfo] = useState(false);
  const { t } = useLokaliseTranslation(['chat', 'general']);
  const { handleCopy } = useMessageCopy(message);
  const { setReply } = useReplayMessageSetter();
  const { closeSearch, isSearchOpen } = useSearchHighlight();
  const { openDialog, closeDialog } = useDialogLayer();
  const messageEditRef = useRef<MessageEditHandle | null>(null);

  const updatePinnedMessages = useUpdatePinnedMessages();

  const enabledMessageInfo = useFeatureFlag(
    FeatureFlags.CHATS_V2_GROUP_BLUE_TICKS,
  );
  const enabledPinMessage = useFeatureFlag(FeatureFlags.CHATS_V2_PIN_MESSAGE);

  const isErrorSendMessage = message.state === StateMessage.ERROR;
  const isAudioMessage =
    message.attachments?.[0]?.metadata.format ===
    FileTypes.AUDIO.toLocaleLowerCase();
  const { hasOnlyTextOrImage } = getMessageContentType({
    attachments: message.attachments || [],
    text: message.text || '',
  });

  const handleCloseMenuMessageInfo = useCallback(() => {
    setOpenMenuMessageInfo(false);
  }, []);

  const closeMenuAndSearch = useCallback(() => {
    onCloseMenu();
    if (isSearchOpen) closeSearch();
  }, [onCloseMenu, closeSearch, isSearchOpen]);

  const handleReply = useCallback(() => {
    closeMenuAndSearch();
    setTimeout(() => {
      setReply(message);
    }, 100);
  }, [closeMenuAndSearch, setReply, message]);

  const handleForward = useCallback(() => {
    openDialog(
      {
        content: (
          <MessageForward
            title={t('chat:forward.send_to')}
            onClose={closeDialog}
            message={message}
          />
        ),
        dialogProps: {
          fullWidth: true,
          maxWidth: 'sm',
          sx: { height: '90%' },
        },
      },
      MESSAGE_FORWARD_DIALOG_ID,
    );
    closeMenuAndSearch();
  }, [closeMenuAndSearch, openDialog, closeDialog, message, t]);

  const handleCopyMessage = useCallback(() => {
    handleCopy();
    onCloseMenu();
  }, [handleCopy, onCloseMenu]);

  const handleEdit = useCallback(() => {
    openDialog(
      {
        content: (
          <MessageEdit
            ref={messageEditRef}
            onClose={closeDialog}
            message={message}
            members={members}
            isGroupConversation={isGroupConversation}
          />
        ),
        dialogProps: {
          fullWidth: true,
          maxWidth: 'sm',
        },
        onClose: reason => {
          if (reason === 'backdropClick') {
            messageEditRef.current?.notifyBackdropClick();
            return;
          }
          if (reason === 'escapeKeyDown') {
            const mentionList = document.getElementById('MentionList');
            if (mentionList) return;
          }
          closeDialog();
        },
      },
      MESSAGE_EDIT_DIALOG_ID,
    );
    closeMenuAndSearch();
  }, [
    closeMenuAndSearch,
    openDialog,
    closeDialog,
    message,
    members,
    isGroupConversation,
  ]);

  const handleReact = useCallback(() => {
    onCloseMenu();
    onReactClick();
  }, [onReactClick, onCloseMenu]);

  const handleOpenMessageInfo = useCallback(() => {
    onCloseMenu();
    setOpenMenuMessageInfo(true);
    const messageType = getTypeMessage(message.attachments, message.text);
    logEvent(EventName.CHATS_2_MESSAGE_INFO_OPENED, {
      messageId: message.ts,
      conversationType: isGroupConversation
        ? CONVERSATION_TYPE.GROUP
        : CONVERSATION_TYPE.INDIVIDUAL,
      conversationId: message.channel,
      messageType,
    });
  }, [onCloseMenu, message, isGroupConversation]);

  const handlePin = useCallback(() => {
    openDialog(
      {
        content: (
          <PinnedMessageModal
            title={t('pin.dialog.title')}
            description={t('pin.dialog.description')}
            options={buildOptions(t, 'pin')}
            onClose={closeDialog}
            onSubmit={(option: string) => {
              updatePinnedMessages.mutate({
                channel: message.channel,
                messageTs: message.hu_data.message_ts,
                expiresAt: getTimeFromOption(option),
              });
            }}
            isLoading={updatePinnedMessages.isLoading}
            primaryButtonLabel={t('pin.pin')}
            pinnedMessagesCount={pinnedMessagesCount}
          />
        ),
        dialogProps: { maxWidth: 'sm', fullWidth: true },
      },
      MESSAGE_PIN_DIALOG_ID,
    );
    closeMenuAndSearch();
  }, [
    closeMenuAndSearch,
    openDialog,
    closeDialog,
    message,
    updatePinnedMessages,
    pinnedMessagesCount,
    t,
  ]);

  const handleUnpin = useCallback(() => {
    updatePinnedMessages.mutate({
      channel: message.channel,
      messageTs: message.hu_data.message_ts,
    });
    closeMenuAndSearch();
  }, [closeMenuAndSearch, updatePinnedMessages, message]);

  const handleDelete = useCallback(() => {
    openDialog(
      {
        content: (
          <MessageDelete
            onClose={closeDialog}
            message={message}
          />
        ),
        dialogProps: { fullWidth: true, maxWidth: 'sm' },
      },
      MESSAGE_DELETE_DIALOG_ID,
    );
    closeMenuAndSearch();
  }, [closeMenuAndSearch, openDialog, closeDialog, message]);

  const menuItems = useMemo(() => {
    if (message?.hidden || isErrorSendMessage) return [];

    return [
      {
        id: 'replay',
        label: t('general:reply'),
        icon: IconShare3,
        onClick: handleReply,
      },
      {
        id: 'forward',
        label: t('chat:forward.forward'),
        icon: IconShare3,
        onClick: handleForward,
      },
      ...(hasOnlyTextOrImage
        ? [
            {
              id: 'copy',
              label: t('general:copy'),
              icon: IconCopy,
              onClick: handleCopyMessage,
            },
          ]
        : []),
      ...(isLoggedUser && !isMessageForwarded && !isAudioMessage
        ? [
            {
              id: 'edit',
              label: t('general:edit'),
              icon: IconEdit,
              onClick: handleEdit,
            },
          ]
        : []),
      {
        id: 'react',
        label: t('chat:messages.react'),
        icon: IconMoodSmile,
        onClick: handleReact,
        disabled: reactions.length >= MAX_EMOJIS_LIMIT,
      },
      ...(enabledMessageInfo && isGroupConversation && isLoggedUser
        ? [
            {
              id: 'info',
              label: t('chat:messages.info'),
              icon: IconInfoCircle,
              onClick: handleOpenMessageInfo,
            },
          ]
        : []),
      ...(enabledPinMessage
        ? [
            {
              id: 'pin',
              label: t(`chat:pin.${isPinnedMessage ? 'unpin' : 'pin'}`),
              icon: isPinnedMessage ? IconPinnedOff : IconPinned,
              onClick: isPinnedMessage ? handleUnpin : handlePin,
            },
          ]
        : []),
      ...(isLoggedUser
        ? [
            {
              id: 'delete',
              label: t('general:delete'),
              icon: IconTrash,
              onClick: handleDelete,
            },
          ]
        : []),
    ];
  }, [
    message,
    isErrorSendMessage,
    t,
    handleReply,
    handleForward,
    hasOnlyTextOrImage,
    handleCopyMessage,
    isLoggedUser,
    isMessageForwarded,
    isAudioMessage,
    handleEdit,
    handleReact,
    reactions.length,
    enabledMessageInfo,
    isGroupConversation,
    handleOpenMessageInfo,
    enabledPinMessage,
    isPinnedMessage,
    handleUnpin,
    handlePin,
    handleDelete,
  ]);

  return { menuItems, openMenuMessageInfo, handleCloseMenuMessageInfo };
};
