import { t } from '@lingui/macro';
import { useLingui } from '@lingui/react';
import { notification, Upload, UploadFile, UploadProps } from 'antd';
import { RcFile } from 'antd/es/upload';
import React from 'react';
import styled from 'styled-components';
import {
  IMAGE_SIZE_LIMIT,
  isFileUnderLimit,
  isImageFile,
  isPDFFile,
  pdf2Images,
} from '../utils/file';
import { bytesToMegabytes } from '../utils/storage';

export function useAntdLocalFiles(uploadProps: UploadProps) {
  const fileUriRef = React.useRef('');
  const [selectedFile, setSelectedFile] = React.useState<UploadFile | null>(
    null,
  );
  const [files, setFiles] = React.useState<UploadFile[]>([]);
  const { i18n } = useLingui();

  const fileValidation = (file) => {
    if (!isImageFile(file) && !isPDFFile(file)) {
      notification.error({
        message: t(i18n)`Upload file validation`,
        description: t(
          i18n,
        )`You are not allowed to upload file other than images (.jpg, .png, .jpeg).`,
      });
      return false;
    }

    if (!isFileUnderLimit(file)) {
      notification.error({
        message: t(i18n)`Upload file validation`,
        description: t(
          i18n,
        )`You are not allowed to upload file bigger than ${bytesToMegabytes(
          IMAGE_SIZE_LIMIT,
        )}MB.`,
      });
      return false;
    }
    return true;
  };

  const onChange: UploadProps['onChange'] = React.useCallback(
    async ({ fileList, file }) => {
      for (file of fileList) {
        if (isPDFFile(file.originFileObj)) {
          const imageFiles = (await pdf2Images(file.originFileObj)) as RcFile[];
          file.originFileObj = imageFiles.shift();
        }
      }

      const isValidFile = fileValidation(file);

      if (isValidFile) {
        if (uploadProps.maxCount === 1 && fileList.length) {
          URL.revokeObjectURL(fileUriRef.current);
          setSelectedFile(fileList[0]);
          fileUriRef.current = URL.createObjectURL(fileList[0].originFileObj);
        }

        setFiles(fileList);
      }
    },
    [uploadProps.maxCount],
  );

  const onPreview: UploadProps['onPreview'] = React.useCallback((file) => {
    URL.revokeObjectURL(fileUriRef.current);
    fileUriRef.current = URL.createObjectURL(file.originFileObj);
    setSelectedFile(file);
  }, []);

  const onRemove: UploadProps['onRemove'] = React.useCallback(
    (file) => {
      if (file.uid === selectedFile?.uid) {
        URL.revokeObjectURL(fileUriRef.current);
        fileUriRef.current = '';
        setSelectedFile(null);
      }

      setFiles((prevFiles) => prevFiles.filter((f) => f.uid !== file.uid));
    },
    [selectedFile],
  );

  const reset = React.useCallback(() => {
    setFiles([]);
    setSelectedFile(null);
    fileUriRef.current = '';
  }, []);

  const antdUploadProps: UploadProps = {
    ...uploadProps,
    onChange,
    onPreview,
    onRemove,
    fileList: files,
    beforeUpload() {
      return false;
    },
  };

  return {
    selectedFileUri: fileUriRef.current,
    selectedFile,
    antdUploadProps,
    fileUriRef,
    reset,
  };
}

export const StyledUpload = styled(Upload)`
  & .ant-upload-list-item-actions > a {
    display: none;
  }
`;
