import { useMutation } from 'react-query';
import { useNavigate } from 'react-router';

import useHuSnackbar from '@material-hu/components/design-system/Snackbar';

import { updateFile, createFiles } from 'src/services/filesService';
import { FileReport, FileType, IFile } from 'src/types/files';
import { removeURLParams, signedUpload } from 'src/utils/filesUtils';
import { useLokaliseTranslation } from 'src/utils/i18n';
import { LogEvents, logEvent } from 'src/utils/logging';
import { formatSegmentationIds } from 'src/utils/segmentationUtils';

import { filesRoutes } from '../routes';
import { getSuccessSnackbarTitle } from '../utils';

type FileRequest = {
  file?: IFile;
  name?: string;
  files: File[];
  showModal?: () => void;
  propagateSegmentation?: boolean;
};

type UseFiles = {
  segmentation: object | null;
  isEditing: boolean;
  parentFolderId?: number;
  showFilesUploadedModal: () => void;
};

export const useFiles = ({
  segmentation,
  isEditing,
  parentFolderId,
  showFilesUploadedModal,
}: UseFiles) => {
  const segment = formatSegmentationIds(segmentation);
  const navigate = useNavigate();
  const { enqueueSnackbar } = useHuSnackbar();
  const { t } = useLokaliseTranslation('files');

  const createFilesFn = async (files: File[]) => {
    const filesUploaded = await Promise.all(
      files.map(async file => {
        const url = await signedUpload(file, false, false, undefined, true);
        const name = file.name;
        return {
          url: removeURLParams(url),
          name,
        };
      }),
    );

    return createFiles(parentFolderId, filesUploaded, segment);
  };

  const trackEvents = (file?: IFile, files?: FileReport[]) => {
    if (isEditing) {
      if (file!.type === FileType.FILE) {
        logEvent(LogEvents.FILE_UPDATE, {
          fileId: file!.id,
          folderId: file!.parentId,
        });
      }
    } else {
      files!.forEach(f =>
        logEvent(LogEvents.FILE_CREATE, {
          folderId: parentFolderId,
          fileId: f?.id,
        }),
      );
    }
  };

  const mutationFn = async (variables: FileRequest) => {
    if (isEditing) {
      return updateFile(
        variables.file!.id,
        variables.name!,
        segment,
        !!variables.propagateSegmentation,
      );
    }
    return createFilesFn(variables.files!);
  };

  const { mutateAsync, isLoading: isMutationLoading } = useMutation(
    mutationFn,
    {
      onSuccess: ({ data: { asyncUpload, filesReport } }, { file, files }) => {
        const showEmailNotificationModal = asyncUpload && !isEditing;
        trackEvents(file, asyncUpload ? files : filesReport); // backend response is empty if async, so we use original files

        if (showEmailNotificationModal) {
          showFilesUploadedModal();
        } else {
          const snackbarTitle = getSuccessSnackbarTitle(
            isEditing,
            t,
            files!.length,
            file?.type,
          );
          enqueueSnackbar({
            title: snackbarTitle,
            variant: 'success',
          });
          navigate(
            file?.type === FileType.FOLDER
              ? (-1 as unknown as string)
              : filesRoutes.file(parentFolderId),
          );
        }
      },
      onError: (_response, variables) => {
        enqueueSnackbar({
          title: t('ERROR', { count: variables.files.length }),
          variant: 'error',
        });
      },
    },
  );

  return { mutateAsync, isMutationLoading };
};
