"use strict";

exports.__esModule = true;
exports.default = void 0;

var _chunkedUploady = require("@rpldy/chunked-uploady");

var _core = require("@selfcommunity/core");

var _uploady = require("@rpldy/uploady");

var _hash = require("../../utils/hash");

var _react = _interopRequireWildcard(require("react"));

var _reactIntl = require("react-intl");

var _common = _interopRequireDefault(require("../../messages/common"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }

function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }

var _default = props => {
  // PROPS
  const {
    type = null,
    onSuccess = null,
    onProgress = null,
    onError = null
  } = props; // REFS

  const firstRender = (0, _react.useRef)(true); // STATE

  const [chunks, setChunks] = (0, _react.useState)({});

  const setChunk = chunk => {
    setChunks(Object.assign({}, chunks, {
      [chunk.id]: Object.assign({}, chunks[chunk.id], chunk)
    }));
  }; // Using refs to have the correct chunks values in the callbacks
  // https://stackoverflow.com/questions/57847594/react-hooks-accessing-up-to-date-state-from-within-a-callback


  const chunkStateRef = _react.default.useRef({
    chunks,
    setChunk,
    setChunks
  });

  chunkStateRef.current = {
    chunks,
    setChunk,
    setChunks
  }; // CONTEXT

  const scContext = (0, _core.useSCContext)(); // INTL

  const intl = (0, _reactIntl.useIntl)(); // component update

  (0, _react.useEffect)(() => {
    if (firstRender.current) {
      firstRender.current = false;
      return;
    }

    onProgress && onProgress(chunks);
  }, [chunks]); // LISTENERS

  (0, _uploady.useItemStartListener)(item => {
    if (item.file.type.startsWith('image/')) {
      const reader = new FileReader();

      reader.onload = e => {
        chunkStateRef.current.setChunk({
          id: item.id,
          image: e.target.result
        });
      }; // eslint-disable-next-line @typescript-eslint/ban-ts-ignore
      // @ts-ignore


      reader.readAsDataURL(item.file);
    }

    chunkStateRef.current.setChunk({
      id: item.id,
      [`upload_id`]: null,
      completed: 0,
      name: item.file.name
    });
  });
  (0, _uploady.useItemProgressListener)(item => {
    chunkStateRef.current.setChunk({
      id: item.id,
      completed: item.completed
    });
  });
  (0, _chunkedUploady.useItemFinishListener)(item => {
    (0, _hash.md5)(item.file, 2142880, hash => {
      const formData = new FormData();
      formData.append('upload_id', chunkStateRef.current.chunks[item.id].upload_id);
      formData.append('type', chunkStateRef.current.chunks[item.id].type);
      formData.append('md5', hash);

      _core.http.request({
        url: _core.Endpoints.ComposerChunkUploadMediaComplete.url(),
        method: _core.Endpoints.ComposerChunkUploadMediaComplete.method,
        data: formData,
        headers: {
          'Content-Type': 'multipart/form-data'
        }
      }).then(res => {
        const _chunks = Object.assign({}, chunkStateRef.current.chunks);

        delete _chunks[item.id];
        chunkStateRef.current.setChunks(_chunks);
        onSuccess(res.data);
      }).catch(error => {
        error = (0, _core.formatHttpError)(error);
        onError(Object.assign({}, chunkStateRef.current.chunks[item.id]), error.error);

        const _chunks = Object.assign({}, chunkStateRef.current.chunks);

        delete _chunks[item.id];
        chunkStateRef.current.setChunks(_chunks);
      });
    });
  });
  (0, _chunkedUploady.useItemErrorListener)(item => {
    onError(Object.assign({}, chunkStateRef.current.chunks[item.id]), intl.formatMessage(_common.default.error));

    const _chunks = Object.assign({}, chunkStateRef.current.chunks);

    delete _chunks[item.id];
    chunkStateRef.current.setChunks(_chunks);
  });
  (0, _chunkedUploady.useChunkStartListener)(data => {
    const res = {
      url: `${scContext.settings.portal}${_core.Endpoints.ComposerChunkUploadMedia.url()}`,
      sendOptions: {
        paramName: 'image',
        headers: {
          Authorization: `Bearer ${scContext.settings.session.authToken.accessToken}`
        },
        method: _core.Endpoints.ComposerChunkUploadMedia.method
      }
    };

    if (chunkStateRef.current.chunks[data.item.id].upload_id) {
      res.sendOptions.params = {
        [`upload_id`]: chunkStateRef.current.chunks[data.item.id].upload_id
      };
    } else {
      chunkStateRef.current.setChunk({
        id: data.item.id,
        type: type || data.sendOptions.paramName
      });
    }

    return res;
  });
  (0, _chunkedUploady.useChunkFinishListener)(data => {
    chunkStateRef.current.setChunk({
      id: data.item.id,
      [`upload_id`]: data.uploadData.response.data.upload_id
    });
  });
  (0, _chunkedUploady.useRequestPreSend)(({
    items,
    options
  }) => {
    if (items.length == 0) {
      return Promise.resolve({
        options
      });
    } //returned object can be wrapped with a promise


    return Promise.resolve({
      options: {
        inputFieldName: options.inputFieldName
      }
    });
  });
  return null;
};

exports.default = _default;