import { FormProvider, useForm, useWatch } from 'react-hook-form';
import { useMutation, useQueryClient } from 'react-query';
import { useParams } from 'react-router-dom';

import { type AxiosError } from 'axios';
import { type GetDrawerConfiguration } from '@material-hu/hooks/useDrawerV2';
import Stack from '@material-hu/mui/Stack';

import useHuSnackbar from '@material-hu/components/design-system/Snackbar';
import HuTitle from '@material-hu/components/design-system/Title';
import HuFormUploader from '@material-hu/components/design-system/Uploader/form';

import { appsKeys } from 'src/pages/dashboard/Apps/queries';
import { type AnyBulkUploadType } from 'src/types/bulk';
import { type ResponseError } from 'src/types/services';
import { useLokaliseTranslation } from 'src/utils/i18n';

import { CardTips } from '../components/CardTips';
import { getErrorDescription, getUploaderService, getWordings } from '../utils';

const UPLOAD_FILE_KEY = 'uploadedFile';

type Props = {
  type: AnyBulkUploadType;
};

type UploadedFile = {
  status: string;
  file: File;
};

const useDrawerUploader: GetDrawerConfiguration<Props> = args => {
  const { t } = useLokaliseTranslation(['backoffice_only', 'material_hu_only']);
  const { type, closeDrawer } = args;
  const { id } = useParams();
  const { title, uploaderTitle, uploaderDescription, tips, submitButton } =
    getWordings(type, t);

  const uploaderService = getUploaderService(type, id);
  const { enqueueSnackbar } = useHuSnackbar();
  const queryClient = useQueryClient();
  const form = useForm<{
    uploadedFile: UploadedFile[];
  }>({
    defaultValues: {
      uploadedFile: [],
    },
  });

  const uploadedFile = useWatch({
    control: form.control,
    name: UPLOAD_FILE_KEY,
  });

  const { mutate, isLoading } = useMutation(
    (file: File) => {
      return uploaderService({ file });
    },
    {
      onSuccess: () => {
        form.reset();
        closeDrawer();
        enqueueSnackbar({
          title: t('backoffice_only:bulk_upload.success'),
          variant: 'info',
        });
        queryClient.invalidateQueries(appsKeys.jobsByType(type));
      },
      onError: (error: AxiosError<ResponseError>, variables) => {
        if (error.response?.data) {
          const errorDescription = getErrorDescription(
            error.response.data,
            t,
            type,
          );
          enqueueSnackbar({
            title: errorDescription,
            variant: 'error',
          });

          form.setValue(UPLOAD_FILE_KEY, [
            {
              status: 'error',
              file: variables,
            },
          ]);
        }
      },
    },
  );

  const onClose = () => {
    form.reset();
    closeDrawer();
  };

  return {
    title: t(title),
    primaryButtonProps: {
      children: t(submitButton),
      onClick: () => {
        const file = form.getValues(UPLOAD_FILE_KEY)[0].file;
        mutate(file);
      },
      loading: isLoading,
      disabled: !uploadedFile.length,
    },
    secondaryButtonProps: {
      children: t('general:cancel'),
      onClick: onClose,
    },
    onClose,
    children: (
      <FormProvider {...form}>
        <Stack sx={{ gap: 2 }}>
          <Stack>
            <HuTitle
              title={uploaderTitle}
              description={uploaderDescription}
              variant="M"
            />
            <HuFormUploader
              name="uploadedFile"
              uploaderProps={{
                sx: { width: '100%' },
                maxFiles: 1,
                acceptedTypes: ['msword'],
                description: uploaderDescription,
                uploadFunction: file => {
                  return new Promise((resolve, reject) => {
                    resolve({ status: 'success', file });
                    reject({ status: 'error', file });
                  });
                },
              }}
            />
          </Stack>
          <CardTips tips={tips} />
        </Stack>
      </FormProvider>
    ),
  };
};

export default useDrawerUploader;
