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

import Stack from '@material-hu/mui/Stack';
import { alpha, type SxProps, useTheme } from '@material-hu/mui/styles';
import Typography from '@material-hu/mui/Typography';

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

import { BUNNY_IMAGE_CLASSES } from 'src/pages/dashboard/Conversations/constants';
import {
  type AttachmentLoadError,
  type ConversationMessage,
  type SendAudiosType,
  type SendFilesList,
} from 'src/pages/dashboard/Conversations/types';
import {
  isImageAttachment,
  isVideoAttachment,
} from 'src/pages/dashboard/Conversations/utils';
import { FileTypes } from 'src/types/attachments';
import { useLokaliseTranslation } from 'src/utils/i18n';

import Gif, { type MediaBaseProps } from 'src/components/attachment/Gif';

import { useReplayMessageSetter } from '../../../contexts/ReplayMessageConversationContext';
import LazySecureAwareImage from '../../shared/LazySecureAwareImage';
import LazySecureAwareVideo from '../../shared/LazySecureAwareVideo';
import LazySecureFile from '../../shared/LazySecureFile';
import MediaVisualizer from '../../shared/MediaVisualizer';

import LazyAudio from './LazyAudio';

const MESSAGE_MEDIA_VISUALIZER_MODAL_ID = 'message-media-visualizer-modal';

type MessageAttachmentsProps = {
  message: ConversationMessage;
  isMessageForwarded: boolean;
  isLoggedUserMessage: boolean;
  isMessageReplied?: boolean;
  onGifError?: () => void;
  nextMessage?: ConversationMessage;
  isLoggedUser: boolean;
};

const MAX_IMAGES_TO_SHOW = 3;
const HIDDEN_IMAGE_COUNT = 2;
const IMAGE_SIZE_THRESHOLD = 2;

const HEIGHT_AUDIO = 45;
const HEIGHT_AUDIO_WITH_REPLY = 65;

const MessageAttachments: FC<MessageAttachmentsProps> = props => {
  const {
    message,
    isMessageForwarded,
    isLoggedUserMessage,
    isMessageReplied = false,
    onGifError,
    nextMessage,
    isLoggedUser,
  } = props;

  const {
    channel: conversationId,
    attachments = [],
    hu_data: huData,
    username,
    text,
    hidden: isDeleted = false,
  } = message;

  const theme = useTheme();
  const { t } = useLokaliseTranslation();
  const [attachmentLoadError, setAttachmentLoadError] =
    useState<AttachmentLoadError>([]);
  const { openDialog, closeDialog } = useDialogLayer();
  const { setReply } = useReplayMessageSetter();
  const handleReply = () => setReply(message);

  if (isDeleted) return null;

  const renderAttachments = (
    attachmentsParam: SendFilesList,
    attchamentLength: number,
  ) => {
    const attachment = attachmentsParam[0];

    if (
      attachment.metadata.format === FileTypes.IMAGE.toLocaleLowerCase() ||
      attachment.metadata.format === FileTypes.VIDEO.toLocaleLowerCase()
    ) {
      const mediaToShow =
        attchamentLength > MAX_IMAGES_TO_SHOW
          ? attachmentsParam?.slice(0, MAX_IMAGES_TO_SHOW)
          : attachmentsParam;
      const remaining = attchamentLength - HIDDEN_IMAGE_COUNT;
      const mediaAttachments = attachments.filter(
        a => isImageAttachment(a) || isVideoAttachment(a),
      );
      return (
        <Stack
          sx={{
            flexDirection: 'row',
            gap: 1,
          }}
        >
          {!!mediaToShow.length &&
            mediaToShow.map((media, index) => {
              const isLastWithOverlay = index === 2 && remaining > 1;

              const sxProps: SxProps = {
                objectFit: 'cover',
                width: '100%',
                height: '100%',
                borderRadius: 2,
                filter: isLastWithOverlay ? 'brightness(0.5)' : 'none',
                '& video': {
                  objectFit: 'cover',
                  height: '100%',
                  width: '100%',
                },
              };
              const isLargeLayout = mediaToShow.length <= IMAGE_SIZE_THRESHOLD;
              const imageSize = isLargeLayout ? 160 : 125;
              const imageClass = isLargeLayout
                ? BUNNY_IMAGE_CLASSES.MSG_IMG_LG
                : BUNNY_IMAGE_CLASSES.MSG_IMG_SM;

              return (
                <Stack
                  key={media.id}
                  sx={{
                    alignItems: 'center',
                    justifyContent: 'center',
                    width: imageSize,
                    height: imageSize,
                    backgroundColor: isLoggedUser
                      ? theme.palette.new.action.background.brand.selected
                      : theme.palette.new.background.layout.brand,
                    position: 'relative',
                    borderRadius: 2,
                    overflow: 'hidden',
                    cursor: 'pointer',
                    pointerEvents:
                      attachmentLoadError.length > 0 ? 'none' : 'auto',
                  }}
                  onClick={() => {
                    const mediaIndex = mediaAttachments.findIndex(
                      a => a.id === media.id,
                    );
                    openDialog(
                      {
                        content: (
                          <MediaVisualizer
                            conversationId={conversationId}
                            text={text}
                            huData={huData}
                            username={username}
                            attachments={mediaAttachments}
                            initialIndex={mediaIndex >= 0 ? mediaIndex : 0}
                            onClose={() =>
                              closeDialog(MESSAGE_MEDIA_VISUALIZER_MODAL_ID)
                            }
                            onReply={() => {
                              handleReply();
                              closeDialog(MESSAGE_MEDIA_VISUALIZER_MODAL_ID);
                            }}
                          />
                        ),
                        dialogProps: {
                          fullScreen: true,
                          PaperProps: { sx: { border: 'none' } },
                        },
                      },
                      MESSAGE_MEDIA_VISUALIZER_MODAL_ID,
                    );
                  }}
                >
                  {isImageAttachment(media) && (
                    <LazySecureAwareImage
                      conversationId={conversationId}
                      isSecure={!!media.isNotSecure}
                      url={media.image_url}
                      alt={media.filename}
                      sxSecure={sxProps}
                      sxDefault={sxProps}
                      imageClass={imageClass}
                      onUpdateAttachmentLoadError={setAttachmentLoadError}
                    />
                  )}
                  {isVideoAttachment(media) && (
                    <LazySecureAwareVideo
                      conversationId={conversationId}
                      isSecure={!!media.isNotSecure}
                      url={media.video_url}
                      thumbUrl={media.thumb_url}
                      sxSecure={sxProps}
                      sxDefault={sxProps}
                      onUpdateAttachmentLoadError={setAttachmentLoadError}
                    />
                  )}
                  {isLastWithOverlay && (
                    <Stack
                      sx={{
                        position: 'absolute',
                        top: 0,
                        left: 0,
                        width: '100%',
                        height: '100%',
                        backgroundColor: theme =>
                          alpha(
                            theme.palette.new.background.elements.inverted,
                            0.8,
                          ),
                        alignItems: 'center',
                        justifyContent: 'center',
                        fontSize: 24,
                        fontWeight: 'bold',
                        borderRadius: 2,
                      }}
                    >
                      <Typography
                        color={theme => theme.palette.new.text.neutral.inverted}
                        variant="globalXL"
                      >
                        +{remaining}
                      </Typography>
                    </Stack>
                  )}
                </Stack>
              );
            })}
        </Stack>
      );
    }

    if (attachment.metadata.format === FileTypes.GIF.toLocaleLowerCase()) {
      return (
        <Stack
          sx={{
            alignItems: 'center',
            justifyContent: 'center',
          }}
        >
          <Gif
            key={attachment.id}
            media={attachment as MediaBaseProps['media']}
            withLimitDuration={true}
            onError={onGifError}
          />
        </Stack>
      );
    }

    if (attachment.metadata.format === FileTypes.FILE.toLocaleLowerCase()) {
      return (
        <Stack
          sx={{
            width: 330,
            height: 76,
            alignItems: 'center',
            justifyContent: 'center',
          }}
        >
          <LazySecureFile
            conversationId={conversationId}
            key={attachment.id}
            file={attachment}
            isDownloadable={true}
            sx={{
              '& .MuiStack-root': {
                minWidth: 0,
              },
            }}
          />
        </Stack>
      );
    }

    if (attachment.metadata.format === FileTypes.AUDIO.toLocaleLowerCase()) {
      return (
        <Stack
          sx={{
            height:
              !isMessageReplied && !isMessageForwarded
                ? HEIGHT_AUDIO
                : HEIGHT_AUDIO_WITH_REPLY,
          }}
        >
          <LazyAudio
            conversationId={conversationId}
            key={attachment.id}
            isLoggedUserMessage={isLoggedUserMessage}
            huData={huData}
            audio={attachment as SendAudiosType}
            username={username}
            isMessageForwarded={isMessageForwarded}
            nextMessage={nextMessage}
            messageTs={huData?.message_ts}
          />
        </Stack>
      );
    }

    return null;
  };

  const handleRetry = () => {
    attachmentLoadError.forEach(error => {
      error.retry?.();
    });
  };

  return (
    <>
      {renderAttachments(attachments, attachments.length)}
      {attachmentLoadError.length > 0 && (
        <Stack
          sx={{
            flexDirection: 'row',
            gap: 1,
          }}
        >
          <Typography variant="globalXXS">{`${t('error_general')}.`}</Typography>
          <Typography
            variant="globalXXS"
            fontWeight="fontWeightSemiBold"
            sx={{
              cursor: 'pointer',
              color: theme.palette.new.graphics.brand[500],
            }}
            onClick={handleRetry}
          >
            {t('try_again')}
          </Typography>
        </Stack>
      )}
    </>
  );
};

export default MessageAttachments;
