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 Stack from '@material-hu/mui/Stack';

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

import { logEvent } from 'src/config/logging';
import { queryClient } from 'src/config/react-query';
import { useRequiredAuth } from 'src/contexts/JWTContext';
import { PROFILE_COVER_IMAGE_ACCEPT } from 'src/pages/dashboard/profile/constants';
import { profileKeys } from 'src/pages/dashboard/profile/queries';
import { uploadImage } from 'src/services/attachments';
import { updateProfilePhoto } 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 { getFullName, getInitials } from 'src/utils/userUtils';

type ProfilePictureProps = {
  user: UserProfile;
};

const ProfilePicture = ({ user }: ProfilePictureProps) => {
  const { t } = useLokaliseTranslation('profile');
  const { user: currentUser, instance } = useRequiredAuth();
  const pictureIsEditable =
    instance.editableProfilePicture && user.id === currentUser.id;

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

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

      const { url } = await uploadImage(newFile);
      if (!url) {
        throw new Error('Missing upload URL');
      }
      await updateProfilePhoto(user.id, url);
      logEvent(EventName.USER_PROFILE_PICTURE_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: (profilePicture: File) =>
        updateProfilePictureMutation.mutateAsync(profilePicture),
      onClose: () => closeModal(),
      recommendedWidth: 500,
      recommendedHeight: 500,
      title: t('edit_profile_picture'),
      round: true,
    },
  );

  return (
    <Stack
      sx={{
        position: 'relative',
        alignSelf: 'flex-end',
        flexShrink: 0,
        width: '20%',
        maxWidth: 152,
        height: 0,
        overflow: 'visible',
      }}
    >
      {croppingModal}
      <Box
        sx={{
          position: 'absolute',
          left: 0,
          bottom: 0,
          width: '100%',
          maxWidth: 152,
          aspectRatio: '1',
          maxHeight: 152,
        }}
      >
        <Avatar
          src={user.profilePicture || undefined}
          text={getInitials(getFullName(user))}
          sx={{
            width: '100%',
            height: '100%',
            backgroundColor: theme =>
              theme.palette.new.background.elements.brand,
            '& img': { objectFit: 'cover' },
            '& .MuiTypography-root': {
              fontSize: 36,
            },
          }}
          variant="circular"
        />
        {pictureIsEditable && (
          <Avatar
            sx={{
              position: 'absolute',
              bottom: '2%',
              right: '2%',
              width: '25%',
              height: '25%',
              cursor: 'pointer',
            }}
            variant="circular"
            Icon={IconCamera}
            onClick={open}
          />
        )}
      </Box>
    </Stack>
  );
};
export default ProfilePicture;
