import { type Dispatch, type FC, type SetStateAction } from 'react';

import {
  IconDownload,
  IconPhoto,
  IconUsersGroup,
} 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 { useTheme } from '@material-hu/mui/index';
import { type SxProps } from '@material-hu/mui/styles';

import HuAvatar from '@material-hu/components/design-system/Avatar';
import { type AvatarProps as HuAvatarProps } from '@material-hu/components/design-system/Avatar/types';
import { getSizeInPixels } from '@material-hu/components/design-system/Avatar/utils';

import { useIntersectionObserver } from 'src/hooks/useIntersectionObserver';
import { type BunnyImageClass } from 'src/pages/dashboard/Conversations/constants';
import { type AttachmentLoadError } from 'src/pages/dashboard/Conversations/types';
import { download, downloadUrl } from 'src/utils/files';
import { useLokaliseTranslation } from 'src/utils/i18n';

import { useGetCorrectAttachmentUrl } from '../../hooks/useConversationsQueries';

type LazySecureImageProps = {
  conversationId?: string;
  url?: string;
  isAvatar?: boolean;
  alt?: string;
  sx?: SxProps;
  avatarProps?: HuAvatarProps;
  onUpdateAttachmentLoadError?: Dispatch<SetStateAction<AttachmentLoadError>>;
  isDownloadable?: boolean;
  filename?: string;
  imageClass?: BunnyImageClass;
};

const LazySecureImage: FC<LazySecureImageProps> = props => {
  const { t } = useLokaliseTranslation('chat');
  const {
    conversationId,
    url = '',
    isAvatar,
    alt = t('groups.picture_group'),
    sx,
    avatarProps,
    onUpdateAttachmentLoadError,
    isDownloadable = false,
    filename = '',
    imageClass,
  } = props;

  const { targetRef, hasBeenVisible } = useIntersectionObserver();
  const theme = useTheme();
  const {
    data,
    isLoading,
    isError: isErrorCorrectImageUrl,
    refetch: refetchCorrectImageUrl,
  } = useGetCorrectAttachmentUrl({
    url,
    conversationId,
    imageClass,
    enabledToShowError: false,
    enabled: !!url && hasBeenVisible,
    onError: () => {
      onUpdateAttachmentLoadError?.(prev => [
        ...(prev ?? []),
        {
          url,
          isError: true,
          retry: () => {
            refetchCorrectImageUrl();
          },
        },
      ]);
    },
    onSuccess: () => {
      onUpdateAttachmentLoadError?.(prev =>
        (prev ?? []).filter(error => error.url !== url),
      );
    },
  });

  const size = isAvatar
    ? getSizeInPixels(avatarProps?.size || 'medium')
    : '24px';

  const handleDownload = (resolvedUrl?: string) => {
    if (!resolvedUrl) return;
    if (resolvedUrl.startsWith('blob:')) {
      download(resolvedUrl, filename);
    } else {
      downloadUrl(resolvedUrl, filename);
    }
  };

  if (isErrorCorrectImageUrl) {
    if (isAvatar) {
      return (
        <Box ref={targetRef}>
          <HuAvatar
            {...avatarProps}
            src={undefined}
            Icon={
              avatarProps?.text
                ? undefined
                : avatarProps?.Icon || IconUsersGroup
            }
          />
        </Box>
      );
    }

    return (
      <Box
        ref={targetRef}
        sx={{ position: 'relative', display: 'inline-flex' }}
      >
        <IconPhoto
          size={size}
          color={theme.palette.new.text.neutral.brand}
        />
        {isDownloadable && (
          <IconButton
            onClick={() => handleDownload(data)}
            variant="secondary"
            size="small"
            sx={{ position: 'absolute', bottom: 0, right: 0 }}
          >
            <IconDownload />
          </IconButton>
        )}
      </Box>
    );
  }

  if (isLoading || !hasBeenVisible || !data) {
    if (isAvatar) {
      return (
        <Box ref={targetRef}>
          <HuAvatar
            {...avatarProps}
            src={undefined}
            Icon={avatarProps?.Icon || IconUsersGroup}
          />
        </Box>
      );
    }

    return (
      <Box ref={targetRef}>
        <CircularProgress size={size} />
      </Box>
    );
  }

  if (isAvatar) {
    return (
      <Box ref={targetRef}>
        <HuAvatar
          {...avatarProps}
          src={data}
          Icon={!data ? IconUsersGroup : undefined}
        />
      </Box>
    );
  }

  return (
    <Box
      ref={targetRef}
      component="img"
      loading="lazy"
      src={data}
      alt={alt}
      sx={{ ...sx }}
    />
  );
};

export default LazySecureImage;
