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

import { IconAlertCircle } from '@material-hu/icons/tabler';
import Stack from '@material-hu/mui/Stack';
import { useTheme } from '@material-hu/mui/styles';
import Typography from '@material-hu/mui/Typography';

import { useAuth } from 'src/contexts/JWTContext';
import {
  type ConversationMessage as ConversationMessageType,
  type Member,
  StateMessage,
} from 'src/pages/dashboard/Conversations/types';
import {
  isForwardedMessage,
  isKnownBlockType,
  isMessageFromDifferentDay,
  isReplyMessage,
} from 'src/pages/dashboard/Conversations/utils';
import { useLokaliseTranslation } from 'src/utils/i18n';

import BubbleContent from './BubbleContent';
import ConversationPill from './ConversationPill';
import MessageSystem from './MessageSystem';

type ConversationMessageProps = {
  message: ConversationMessageType;
  prevMessage?: ConversationMessageType;
  nextMessage?: ConversationMessageType;
  members: Member[];
  isGroupConversation: boolean;
  isSelfConversation: boolean;
};

const ConversationMessage: FC<ConversationMessageProps> = props => {
  const {
    message,
    members,
    isGroupConversation,
    prevMessage,
    isSelfConversation,
    nextMessage,
  } = props;
  const { user: loggedUser } = useAuth();
  const { t } = useLokaliseTranslation('chat');

  const theme = useTheme();
  const isErrorSendMessage = message.state === StateMessage.ERROR;
  const isLoggedUser = Number(message.user) === loggedUser?.id;

  const isDifferentDay = prevMessage
    ? isMessageFromDifferentDay(message.ts, prevMessage.ts)
    : false;

  const showUserPic =
    !prevMessage ||
    prevMessage.user !== message.user ||
    !!prevMessage?.blocks ||
    (prevMessage.user === message.user && isDifferentDay);

  const messageBlocks = message?.blocks && message.blocks;
  const isKnownBlock = messageBlocks && isKnownBlockType(messageBlocks);
  const isMessageReplied = messageBlocks && isReplyMessage(messageBlocks);
  const isMessageForwarded = messageBlocks && isForwardedMessage(messageBlocks);

  if (messageBlocks && message.hidden) {
    return null;
  }

  if (
    messageBlocks &&
    isKnownBlock &&
    !isMessageReplied &&
    !isMessageForwarded
  ) {
    return (
      <MessageSystem
        message={message}
        systemMessages={messageBlocks}
      />
    );
  }

  return (
    <Stack
      sx={{
        flexDirection: 'row',
        width: '100%',
        alignItems: 'center',
        justifyContent: isLoggedUser ? 'flex-end' : 'flex-start',
      }}
    >
      <Stack sx={{ gap: 1 }}>
        <Stack
          sx={{
            flexDirection:
              isLoggedUser && !isErrorSendMessage ? 'row-reverse' : 'row',
            alignSelf: isErrorSendMessage ? 'flex-end' : 'flex-start',
            gap: 1,
          }}
        >
          {isGroupConversation && !isLoggedUser && (
            <ConversationPill
              message={message}
              showUserPic={showUserPic}
            />
          )}
          <BubbleContent
            message={message}
            nextMessage={nextMessage}
            members={members}
            isLoggedUser={isLoggedUser}
            isGroupConversation={isGroupConversation}
            showUserPic={showUserPic}
            isSystemMessage={Boolean(messageBlocks)}
            isKnownBlock={isKnownBlock || false}
            isMessageReplied={isMessageReplied}
            isMessageForwarded={isMessageForwarded}
            isSelfConversation={isSelfConversation}
          />
          <Stack
            sx={{
              alignSelf: 'stretch',
              justifyContent: 'space-between',
            }}
          >
            <Stack>
              {isErrorSendMessage && (
                <IconAlertCircle
                  color={theme.palette.new.text.neutral.lighter}
                />
              )}
            </Stack>
          </Stack>
        </Stack>
        {isErrorSendMessage && (
          <Typography variant="globalXXS">
            {t('errors.no_send_message')}
          </Typography>
        )}
      </Stack>
    </Stack>
  );
};

export default memo(ConversationMessage);
