import { Dispatch, FC, SetStateAction, useMemo, useState } from 'react';
import { useMutation } from 'react-query';

import FileUploadIcon from '@material-hu/icons/material/FileUpload';
import Box from '@material-hu/mui/Box';
import CircularProgress from '@material-hu/mui/CircularProgress';
import Stack from '@material-hu/mui/Stack';

import useGeneralError from 'src/hooks/useGeneralError';
import { uploadFile } from 'src/services/attachments';
import { getAttachment } from 'src/utils/files';
import { useLokaliseTranslation } from 'src/utils/i18n';

import {
  AttachmentsAdd,
  AttachmentsFileList,
  AttachmentsList,
} from 'src/components/attachment';

export type FileInputProps = {
  onChange: (values: any) => void;
  inputFile?: any;
  answerInput?: any[];
  disabled?: boolean;
  loading: boolean;
  name: string;
  setUploadingFiles?: Dispatch<SetStateAction<Record<string, boolean>>>;
};

export const FileInput: FC<FileInputProps> = props => {
  const {
    onChange,
    inputFile,
    answerInput,
    disabled,
    setUploadingFiles,
    loading,
    name,
  } = props;

  const [files, setFiles] = useState(inputFile || []);
  const { t } = useLokaliseTranslation('forms');
  const showGeneralError = useGeneralError();

  const { mutateAsync: uploadFileInForm } = useMutation(uploadFile, {
    onMutate: () => {
      setUploadingFiles(prev => ({
        ...prev,
        [name]: true,
      }));
    },
    onError: err => {
      showGeneralError(err, t('NO_UPLOAD_FILES'));
    },
    onSettled: () => {
      setUploadingFiles(prev => {
        const newUploadingFiles = { ...prev };
        delete newUploadingFiles[name];
        return newUploadingFiles;
      });
    },
  });

  const handleAddFile = async file => {
    const fileFormated = await uploadFileInForm(file);

    if (!fileFormated || !fileFormated.url || !fileFormated.size) {
      showGeneralError(null, t('NO_UPLOAD_FILES'));
      return;
    }

    setFiles([...files, file]);

    onChange([
      ...(Array.isArray(inputFile) ? inputFile : []),
      {
        ...file,
        url: fileFormated.url,
        size: fileFormated.size,
      },
    ]);
  };

  const handleDelete = (_, index) => {
    const newList = [...files];
    newList.splice(index, 1);
    setFiles(newList);
    files.length ? onChange(newList) : onChange(undefined);
  };

  const filesAttach = useMemo(() => files.map(getAttachment), [files]);

  return (
    <>
      <Stack
        sx={{
          textAlign: 'center',
          gap: 1,
          flexDirection: 'row',
          alignItems: 'center',
          justifyContent: 'center',
        }}
      >
        <AttachmentsAdd
          disabled={disabled}
          iconCustomFile={<FileUploadIcon fontSize="large" />}
          onAddFile={handleAddFile}
        />
        {loading && <CircularProgress size={16} />}
      </Stack>
      {files?.length > 0 && (
        <AttachmentsList
          sx={{ my: 2, mx: 2 }}
          files={answerInput || filesAttach}
          onDelete={handleDelete}
        />
      )}
      {answerInput?.length > 0 && (
        <Box>
          <AttachmentsFileList
            files={answerInput}
            enableOpenFile
          />
        </Box>
      )}
    </>
  );
};

export default FileInput;
