import { type FC } from 'react';
import { useParams } from 'react-router-dom';

import { IconPlayerPlay, IconX } from '@material-hu/icons/tabler';
import Box from '@material-hu/mui/Box';
import CircularProgress from '@material-hu/mui/CircularProgress';
import IconButton from '@material-hu/mui/IconButton';
import Stack from '@material-hu/mui/Stack';
import { alpha, useTheme } from '@material-hu/mui/styles';

import HuAvatar from '@material-hu/components/design-system/Avatar';
import HuFileCard from '@material-hu/components/design-system/FileCard';
import { useDialogLayer } from '@material-hu/components/layers/Dialogs';

import { useAuth } from 'src/contexts/JWTContext';
import {
  type SendFileItem,
  type SendFilesList,
  type SendFileType,
} from 'src/pages/dashboard/Conversations/types';
import {
  isImageAttachment,
  isVideoAttachment,
} from 'src/pages/dashboard/Conversations/utils';
import { bytesToSize } from 'src/utils/bytes';
import { getFullName } from 'src/utils/userUtils';

import MediaVisualizer from '../../shared/MediaVisualizer';

const FOOTER_MEDIA_VISUALIZER_ID = 'footer-media-visualizer';
type ShowAttachmentSelectedProps = {
  attachments: SendFilesList;
  isLoadingFiles: boolean;
  updateAttachments: (array?: SendFileItem[]) => void;
  cancelUpload: (attachment: SendFileItem) => void;
  body?: string;
};

const ShowAttachmentSelected: FC<ShowAttachmentSelectedProps> = props => {
  const { attachments, isLoadingFiles, updateAttachments, cancelUpload, body } =
    props;
  const { id: conversationId } = useParams<{ id: string }>();
  const { user } = useAuth();
  const username = getFullName(user ?? null);
  const theme = useTheme();
  const { openDialog, closeDialog } = useDialogLayer();

  const emptyAttachments = () => updateAttachments();

  const renderAttachments = (attachment: SendFileItem) => {
    const handleOnClick = (
      e: React.MouseEvent,
      attachmentParam: SendFileItem,
    ) => {
      e.stopPropagation();
      cancelUpload(attachmentParam);
    };

    const handleOpenFile = (fileUrl: string) =>
      window.open(fileUrl, '_blank', 'noopener,noreferrer');

    const handleShowMedia = (isLoading?: boolean) => {
      if (isLoading) return;

      const mediaAttachments = attachments.filter(
        attachment =>
          isImageAttachment(attachment) || isVideoAttachment(attachment),
      );

      openDialog(
        {
          content: (
            <MediaVisualizer
              conversationId={conversationId}
              username={username}
              attachments={mediaAttachments}
              onClose={() => closeDialog(FOOTER_MEDIA_VISUALIZER_ID)}
              text={body}
              isSecure
            />
          ),
          dialogProps: {
            fullScreen: true,
            PaperProps: { sx: { border: 'none' } },
          },
        },
        FOOTER_MEDIA_VISUALIZER_ID,
      );
    };

    const buttonToDeleteFile = (
      <IconButton
        size="small"
        onClick={e => handleOnClick(e, attachment)}
        sx={{
          backgroundColor: alpha(
            theme.palette.new.background.layout.default,
            0.5,
          ),
          position: 'absolute',
          zIndex: 1,
          top: -12,
          right: -12,
        }}
        variant="tertiary"
      >
        <IconX color={theme.palette.new.text.neutral.default} />
      </IconButton>
    );

    if (isVideoAttachment(attachment)) {
      return (
        <Stack
          key={attachment.id}
          sx={{
            position: 'relative',
            cursor: attachment.isLoading ? 'default' : 'pointer',
          }}
          onClick={() => handleShowMedia(attachment.isLoading)}
        >
          <Box
            sx={{
              width: 85,
              height: 85,
              filter: attachment.isLoading ? 'blur(1px)' : 'none',
              '& video': {
                objectFit: 'cover',
                borderRadius: 2,
              },
            }}
          >
            <video
              width="100%"
              height="100%"
              controls={false}
              src={
                attachment.isLoading
                  ? attachment.video_url
                  : attachment.local_video_url
              }
            />
          </Box>
          <Box
            sx={{
              position: 'absolute',
              top: 0,
              left: 0,
              width: '100%',
              height: '100%',
              display: 'flex',
              alignItems: 'center',
              justifyContent: 'center',
            }}
          >
            {attachment.isLoading ? (
              <CircularProgress
                size={32}
                thickness={5}
              />
            ) : (
              <HuAvatar Icon={IconPlayerPlay} />
            )}
          </Box>
          {buttonToDeleteFile}
        </Stack>
      );
    }

    if (isImageAttachment(attachment)) {
      return (
        <Stack
          key={attachment.id}
          sx={{
            position: 'relative',
            cursor: attachment.isLoading ? 'default' : 'pointer',
          }}
          onClick={() => handleShowMedia(attachment.isLoading)}
        >
          <Box
            component="img"
            src={attachment.local_image_url ?? attachment.image_url}
            alt="preview"
            sx={{
              width: 85,
              height: 85,
              borderRadius: 2,
              objectFit: 'cover',
              filter: attachment.isLoading ? 'blur(1px)' : 'none',
              cursor: attachment.isLoading ? 'default' : 'pointer',
            }}
          />

          {attachment.isLoading && (
            <Box
              sx={{
                position: 'absolute',
                inset: 0,
                display: 'flex',
                alignItems: 'center',
                justifyContent: 'center',
              }}
            >
              <CircularProgress
                size={32}
                thickness={5}
              />
            </Box>
          )}
          {buttonToDeleteFile}
        </Stack>
      );
    }

    const fileAttachment = attachment as SendFileType;

    return (
      <Stack
        key={attachment.id}
        sx={{ position: 'relative' }}
      >
        {attachment.isLoading && (
          <HuFileCard
            status="uploading"
            showDownloadButton={false}
            file={fileAttachment.file}
          />
        )}
        {!attachment.isLoading && (
          <Stack
            sx={{ cursor: 'pointer' }}
            onClick={() =>
              handleOpenFile(
                isVideoAttachment(attachment)
                  ? attachment.video_url
                  : fileAttachment.url,
              )
            }
          >
            <HuFileCard
              status="default"
              showDownloadButton={false}
              attachment={{
                url: isVideoAttachment(attachment)
                  ? attachment.video_url
                  : fileAttachment.url,
                name: attachment.filename,
                type: attachment.mimetype,
                size: bytesToSize(fileAttachment.size),
                bytes: fileAttachment.size,
              }}
            />
          </Stack>
        )}
        {buttonToDeleteFile}
      </Stack>
    );
  };

  return (
    <Stack>
      <IconButton
        size="small"
        disabled={isLoadingFiles}
        onClick={emptyAttachments}
        variant="tertiary"
        sx={{ alignSelf: 'flex-end' }}
      >
        <IconX color={theme.palette.new.text.neutral.default} />
      </IconButton>
      <Stack
        sx={{
          flexDirection: 'row',
          width: '100%',
          gap: 2,
          overflowX: 'scroll',
          pt: 3,
          pb: 2,

          '::-webkit-scrollbar': {
            height: '0px',
            background: 'transparent',
          },
          '::-webkit-scrollbar-thumb': {
            borderRadius: '0px',
            backgroundColor: 'transparent',
          },
          '::-webkit-scrollbar-track': {
            background: 'transparent',
          },
        }}
      >
        {attachments.map(renderAttachments)}
      </Stack>
    </Stack>
  );
};

export default ShowAttachmentSelected;
