import { useDropzone } from 'react-dropzone';
import { useMutation } from 'react-query';

import { useModal } from '@material-hu/hooks/useModal';
import { IconCamera } from '@material-hu/icons/tabler';
import Box from '@material-hu/mui/Box';

import CroppingModal from '@material-hu/components/composed-components/CroppingModal';
import Button from '@material-hu/components/design-system/Buttons/Button';

import { logEvent } from 'src/config/logging';
import { queryClient } from 'src/config/react-query';
import { useRequiredAuth } from 'src/contexts/JWTContext';
import { uploadImage } from 'src/services/attachments';
import { updateUserCoverPicture } from 'src/services/files';
import { EventName } from 'src/types/amplitude';
import { FileTypes } from 'src/types/attachments';
import { type UserProfile } from 'src/types/user';
import { useLokaliseTranslation } from 'src/utils/i18n';

import {
  COVER_RECOMMENDED_HEIGHT,
  COVER_RECOMMENDED_WIDTH,
  PROFILE_COVER_IMAGE_ACCEPT,
} from '../constants';
import { profileKeys } from '../queries';

type EditCoverPictureButtonProps = {
  user: UserProfile;
};

const EditCoverPictureButton = ({ user }: EditCoverPictureButtonProps) => {
  const { t } = useLokaliseTranslation('profile');
  const { user: currentUser, instance } = useRequiredAuth();

  const updateCoverMutation = useMutation({
    mutationFn: async (coverFile: File) => {
      const newFile = {
        name: coverFile.name,
        size: coverFile.size,
        mime: coverFile.type,
        fileObject: coverFile,
        type: FileTypes.IMAGE,
      };

      const { url } = await uploadImage(newFile);
      if (!url) {
        throw new Error('Missing upload URL');
      }
      await updateUserCoverPicture(user.id, url);
      logEvent(EventName.USER_PROFILE_COVER_UPDATE);
      return queryClient.invalidateQueries({
        queryKey: profileKeys.detail(user.id),
      });
    },
  });

  const {
    modal: croppingModal,
    showModal: showCroppingModal,
    closeModal,
  } = useModal(
    CroppingModal,
    { fullWidth: true, maxWidth: 'md' },
    {
      cancelLabel: t('general:cancel'),
      saveLabel: t('general:save'),
      onSave: (coverFile: File) => updateCoverMutation.mutateAsync(coverFile),
      onClose: () => closeModal(),
      recommendedWidth: COVER_RECOMMENDED_WIDTH,
      recommendedHeight: COVER_RECOMMENDED_HEIGHT,
      title: t('EDIT_COVER_PICTURE'),
    },
  );

  const { open } = useDropzone({
    onDrop: files => {
      if (files[0]) {
        showCroppingModal({ file: files[0] });
      }
    },
    accept: PROFILE_COVER_IMAGE_ACCEPT,
    maxFiles: 1,
    noClick: true,
  });

  const canEditCover =
    user.id === currentUser.id && instance.editableCoverPicture;

  return (
    <>
      {canEditCover && (
        <Box
          sx={{
            position: 'absolute',
            top: 24,
            right: 24,
            zIndex: 1,
          }}
        >
          {croppingModal}
          <Button
            variant="secondary"
            startIcon={<IconCamera />}
            onClick={open}
          >
            {t('edit_cover')}
          </Button>
        </Box>
      )}
    </>
  );
};

export default EditCoverPictureButton;
