import { forwardRef, useImperativeHandle, useState } from 'react';
import { FormProvider, useForm } from 'react-hook-form';

import { IconSend } from '@material-hu/icons/tabler';
import IconButton from '@material-hu/mui/IconButton';
import Stack from '@material-hu/mui/Stack';

import HuDialog from '@material-hu/components/design-system/Dialog';

import {
  type ConversationMessage,
  type Member,
  MessageTypeSocket,
} from 'src/pages/dashboard/Conversations/types';
import {
  convertMessageToTipTapFormat,
  extractHighlightedSpans,
} from 'src/pages/dashboard/Conversations/utils';
import { useLokaliseTranslation } from 'src/utils/i18n';

import { type LoadingButtonProps } from 'src/components/LoadingButton';

import { useEditMessage } from '../../hooks/useConversationsQueries';
import InputEditor from '../ConversationsThread/ConversationsThreadFooter/InputEditor';

export type MessageEditHandle = {
  notifyBackdropClick: () => void;
};

export type MessageEditProps = {
  onClose: () => void;
  message: ConversationMessage;
  members: Member[];
  isGroupConversation?: boolean;
};

const MessageEdit = forwardRef<MessageEditHandle, MessageEditProps>(
  function MessageEdit(
    { onClose, message, members, isGroupConversation },
    ref,
  ) {
    const [isClickedOutside, setIsClickedOutside] = useState(false);
    const { t } = useLokaliseTranslation(['chat', 'general']);
    // TODO: remove this when useDialogLayer has the fix.
    useImperativeHandle(
      ref,
      () => ({
        notifyBackdropClick: () => setIsClickedOutside(true),
      }),
      [],
    );

    const processedContent = convertMessageToTipTapFormat({
      messageText: message.text || '',
      mentionSpans: message.hu_data?.highlighted_spans || [],
      t,
    });

    const form = useForm({
      defaultValues: {
        body: message.text || '',
      },
      mode: 'onChange',
    });
    const {
      handleSubmit,
      formState: { isSubmitting, isDirty },
      watch,
    } = form;

    const {
      mutateAsync: editMessageMutation,
      isLoading: isLoadingEditMessage,
    } = useEditMessage({
      onClose,
    });

    const title = isClickedOutside
      ? t('chat:edit.confirm')
      : t('chat:edit.title');
    const primaryButtonProps = isClickedOutside
      ? {
          children: t('chat:discard'),
          onClick: () => {
            onClose();
          },
        }
      : undefined;
    const secondaryButtonProps = isClickedOutside
      ? {
          children: t('general:cancel'),
          onClick: () => {
            setIsClickedOutside(false);
          },
        }
      : undefined;

    const handleEditMessage = async (values: { body: string }) => {
      const cleanedBody = values.body ? values.body.trim() : '';

      if (!cleanedBody) {
        return;
      }

      const highlightedSpans = extractHighlightedSpans(cleanedBody);

      const { edited } = message;
      const msgEdited: ConversationMessage = {
        ...message,
        edited: {
          user: message.user,
          ts: message.hu_data.message_ts,
        },
        hu_data: {
          ...message.hu_data,
          highlighted_spans: highlightedSpans,
        },
        text: cleanedBody,
        ts: edited ? edited.ts : message.hu_data.message_ts,
        type: MessageTypeSocket.UPDATE,
      };
      await editMessageMutation({
        msgEdited,
      });
    };

    return (
      <HuDialog
        title={title}
        primaryButtonProps={primaryButtonProps as LoadingButtonProps}
        secondaryButtonProps={secondaryButtonProps as LoadingButtonProps}
        body={
          !isClickedOutside && (
            <FormProvider {...form}>
              <form
                onSubmit={handleSubmit(handleEditMessage)}
                style={{ width: '100%' }}
              >
                <Stack
                  sx={{
                    flexDirection: 'row',
                    gap: 1,
                    paddingY: 2,
                    paddingLeft: 0,
                    paddingRight: 3,
                    mb: 1.5,
                  }}
                >
                  <InputEditor
                    name="body"
                    content={processedContent}
                    disabled={isSubmitting || isLoadingEditMessage}
                    members={members}
                    isPopper={true}
                    isGroupConversation={isGroupConversation}
                    clearOnSubmit={false}
                    mode="emoji"
                  />
                  <IconButton
                    disabled={
                      isSubmitting ||
                      !watch('body')?.trim() ||
                      isLoadingEditMessage ||
                      !isDirty
                    }
                    onClick={() => handleSubmit(handleEditMessage)()}
                    variant="primary"
                    sx={{
                      width: '40px',
                      height: '40px',
                    }}
                  >
                    <IconSend />
                  </IconButton>
                </Stack>
              </form>
            </FormProvider>
          )
        }
        onClose={onClose}
      />
    );
  },
);

export default MessageEdit;
