import { useFormContext } from 'react-hook-form';

import { ErrorCode, type FileRejection } from '@humanddev/material-hu/dropzone';

import useSnackbar from '@material-hu/components/design-system/Snackbar';
import FormUploader from '@material-hu/components/design-system/Uploader/form';

import { useLokaliseTranslation } from 'src/utils/i18n';
import { optionalLabel } from 'src/utils/stringUtils';

import { MAX_FILE_SIZE_BYTES, MAX_FILE_SIZE_MB } from '../../constants';
import {
  type FileCardTypeWithId,
  type JobDetailCandidateForm,
} from '../../types';

export const CVUploader = ({
  onUploadFile,
}: {
  onUploadFile: (file: File) => Promise<FileCardTypeWithId>;
}) => {
  const { t } = useLokaliseTranslation(['ats', 'material_hu_only']);
  const { enqueueSnackbar } = useSnackbar();
  const { clearErrors, setValue } = useFormContext<JobDetailCandidateForm>();

  const handleDropRejected = (fileRejections: FileRejection[]) => {
    if (!fileRejections?.length && !fileRejections[0]?.errors?.length) return;

    const isTooLarge =
      fileRejections[0].errors[0].code === ErrorCode.FileTooLarge;

    // Clear cv form error and value to allow the form to be valid again
    clearErrors('cv');
    setValue('cv', undefined, { shouldValidate: true, shouldDirty: true });

    if (isTooLarge) {
      enqueueSnackbar({
        title: t('common.error_files.error_size', { size: MAX_FILE_SIZE_MB }),
        variant: 'error',
      });
      return;
    }

    const isTooManyFiles =
      fileRejections[0].errors[0].code === ErrorCode.TooManyFiles;

    if (isTooManyFiles) {
      enqueueSnackbar({
        title: t('common.error_files.error_count', { count: 1 }),
        variant: 'error',
      });
      return;
    }

    enqueueSnackbar({
      title: t('common.error_files.error_add'),
      variant: 'error',
    });
  };

  const cvPlaceholderDescription = t('common.files_allowed.base', {
    formats: t('common.files_allowed.image_and_text'),
    size: MAX_FILE_SIZE_MB,
  });

  return (
    <FormUploader
      name="cv"
      uploaderProps={{
        label: optionalLabel(
          t('job_candidates.new.fields.cv.label'),
          t('common.optional'),
        ),
        maxFiles: 1,
        showUploadButtonOnMaxFiles: false,
        triggerOnChangeWhenUploading: true,
        acceptedTypes: ['pdf', 'image', 'msword'],
        fileSizeLimit: MAX_FILE_SIZE_BYTES,
        uploadFunction: onUploadFile,
        description: cvPlaceholderDescription,
        onDropRejected: handleDropRejected,
        slotProps: {
          fileCard: {
            showReuploadButton: false,
          },
        },
        sx: {
          '& .MuiStack-root[role="presentation"]': {
            backgroundColor: theme =>
              theme.palette.new.background.layout.tertiary,
          },
        },
      }}
    />
  );
};
