import { type DropEvent, type FileRejection } from 'react-dropzone';
import { Controller, useFormContext } from 'react-hook-form';
import { useTranslation } from 'react-i18next';

import { type FileCardType } from '@design-system/FileCard/types';

import { type FormUploaderProps } from './types';
import { exceedsMaxFiles } from './utils';
import Uploader from '.';

const FormUploader = ({
  children,
  name,
  uploaderProps,
  rules,
  fileCardProps,
}: FormUploaderProps) => {
  const form = useFormContext();
  const { t } = useTranslation('material_hu_only');

  const maxFiles = uploaderProps.maxFiles;
  const files = form.watch(name);

  const onDropAccepted = (filesAccepted: File[]) => {
    const countFilesUploaded = filesAccepted?.length + files?.length;
    if (exceedsMaxFiles(countFilesUploaded, maxFiles)) {
      return form.setError(name, {
        message: t('uploader.max_files_error', {
          maxFiles: maxFiles,
        }),
      });
    }
    form.clearErrors();

    return uploaderProps.onDropAccepted?.(filesAccepted);
  };

  const onDropRejected = (filesRejected: FileRejection[], event: DropEvent) => {
    if (exceedsMaxFiles(filesRejected.length, maxFiles)) {
      form.setError(name, {
        message: t('uploader.max_files_error', {
          maxFiles: maxFiles,
        }),
      });
    } else {
      form.setError(name, {
        message:
          !uploaderProps.maxFiles || uploaderProps.maxFiles > 1
            ? t('uploader.some_file_not_uploaded')
            : t('uploader.file_not_uploaded'),
      });
    }

    return uploaderProps.onDropRejected?.(filesRejected, event);
  };

  const onFilesUploaded = (filesUploaded: FileCardType[]) => {
    uploaderProps.onFilesUploaded?.(filesUploaded);
  };

  const disabled =
    (maxFiles && files?.length >= maxFiles) || uploaderProps.disabled;

  return (
    <Controller
      render={({ field, fieldState }) => {
        return (
          <Uploader
            {...field}
            {...uploaderProps}
            onDropRejected={onDropRejected}
            helperText={fieldState.error?.message || uploaderProps.helperText}
            error={!!fieldState.error}
            disabled={disabled}
            onDropAccepted={onDropAccepted}
            onFilesUploaded={onFilesUploaded}
            fileCardProps={fileCardProps}
          >
            {children}
          </Uploader>
        );
      }}
      name={name}
      rules={rules}
    />
  );
};

export default FormUploader;
