'use strict';

var defineProperty = require('../../../defineProperty-lChFfVqi.js');
var _typeof = require('../../../typeof-D4ZZ_FlZ.js');
var neetoAtoms = require('@bigbinary/neeto-atoms');
var axios = require('axios');
var i18next = require('i18next');
var neetoCist = require('@bigbinary/neeto-cist');
var ramda = require('ramda');
var reactToastify = require('react-toastify');
var v2_reactUtils_useDisplayErrorPage_useDisplayErrorPage = require('../../react-utils/useDisplayErrorPage/useDisplayErrorPage.js');
var v2_utils_axios = require('../../utils/axios.js');
var v2_initializers_axiosInitializer_paramsSerializer = require('./paramsSerializer.js');
var v2_initializers_constants = require('../constants.js');
require('zustand');
require('qs');

var checkOnlineInterval = null;
var requestErrorToasts = {};
var shouldNot = function shouldNot(skip) {
  return _typeof._typeof(skip) === "object" || !skip;
};
var shouldShowToastr = function shouldShowToastr(response) {
  return typeof response === "string" && neetoCist.isNotEmpty(response) || _typeof._typeof(response) === "object" && ((response === null || response === void 0 ? void 0 : response.notice) || (response === null || response === void 0 ? void 0 : response.noticeCode));
};
var setAuthHeaders = function setAuthHeaders() {
  var _document$querySelect;
  // @ts-ignore
  axios.defaults.headers = defineProperty._defineProperty(defineProperty._defineProperty(defineProperty._defineProperty({}, v2_initializers_constants.HEADERS_KEYS.accept, "application/json"), v2_initializers_constants.HEADERS_KEYS.contentType, "application/json"), v2_initializers_constants.HEADERS_KEYS.xCsrfToken, (_document$querySelect = document.querySelector('[name="csrf-token"]')) === null || _document$querySelect === void 0 ? void 0 : _document$querySelect.getAttribute("content"));
};

// pipe function from ramda doesn't accept array of functions.
// We can't use spread operator too. So this is a workaround.
var createPipe = function createPipe(functions) {
  return function (data) {
    return functions.reduce(function (acc, fn) {
      return fn(acc);
    }, data);
  };
};
var transformResponseKeysToCamelCase = function transformResponseKeysToCamelCase(response) {
  var _response$config$tran = response.config.transformResponseCase,
    transformResponseCase = _response$config$tran === void 0 ? true : _response$config$tran;
  if (response.data && transformResponseCase) {
    response.data = neetoCist.keysToCamelCase(response.data);
  }
  return response;
};
var transformErrorKeysToCamelCase = function transformErrorKeysToCamelCase(error) {
  var _error$config, _error$response;
  var _ref = (_error$config = error.config) !== null && _error$config !== void 0 ? _error$config : {},
    _ref$transformRespons = _ref.transformResponseCase,
    transformResponseCase = _ref$transformRespons === void 0 ? true : _ref$transformRespons;
  if ((_error$response = error.response) !== null && _error$response !== void 0 && _error$response.data && transformResponseCase) {
    error.response.data = neetoCist.keysToCamelCase(error.response.data);
  }
  return error;
};
var showSuccessToastr = function showSuccessToastr(response) {
  var _response$config = response.config,
    _response$config$show = _response$config.showToastr,
    showToastr = _response$config$show === void 0 ? true : _response$config$show,
    requestUrl = _response$config.url,
    requestMethod = _response$config.method;
  if (!showToastr) return response;
  var toastIdKey = "".concat(requestMethod, ":").concat(requestUrl);
  var errorToastId = requestErrorToasts[toastIdKey];
  if (errorToastId) {
    reactToastify.toast.dismiss(errorToastId);
    requestErrorToasts = ramda.dissoc(toastIdKey, requestErrorToasts);
  }
  if (neetoCist.matches({
    showThumbsUpToastr: true
  }, response.data)) {
    neetoAtoms.Toastr.success("👍", {
      showIcon: false
    });
  } else if (neetoCist.matches({
    noticeCode: "thumbs_up"
  }, response.data)) {
    neetoAtoms.Toastr.success("👍", {
      showIcon: false
    });
  } else if (shouldShowToastr(response.data)) {
    neetoAtoms.Toastr.success(response.data);
  }
  return response;
};
var pullDataFromResponse = function pullDataFromResponse(response) {
  var _response$config$incl = response.config.includeMetadataInResponse,
    includeMetadataInResponse = _response$config$incl === void 0 ? false : _response$config$incl;
  return includeMetadataInResponse ? response : response.data;
};
var checkForReleaseVersionMismatch = function checkForReleaseVersionMismatch(response) {
  var _res$headers, _globalProps;
  var res = (response === null || response === void 0 ? void 0 : response.response) || response;
  var newReleaseVersion = Number(res === null || res === void 0 || (_res$headers = res.headers) === null || _res$headers === void 0 ? void 0 : _res$headers["x-deploy-release-version"]);
  var currentReleaseVersion = Number((_globalProps = globalProps) === null || _globalProps === void 0 ? void 0 : _globalProps.deployReleaseVersion);
  if (newReleaseVersion && currentReleaseVersion && newReleaseVersion !== currentReleaseVersion) {
    v2_reactUtils_useDisplayErrorPage_useDisplayErrorPage.useErrorDisplayStore.setState({
      showRefreshRibbon: true
    });
  }
  return response;
};
var buildSuccessResponseHandler = function buildSuccessResponseHandler(skip) {
  var interceptors = [];
  if (!(skip !== null && skip !== void 0 && skip.transformCase)) interceptors.push(transformResponseKeysToCamelCase);
  if (!(skip !== null && skip !== void 0 && skip.showToastr)) interceptors.push(showSuccessToastr);
  if (!(skip !== null && skip !== void 0 && skip.checkForReleaseVersionMismatch)) {
    interceptors.push(checkForReleaseVersionMismatch);
  }
  if (!(skip !== null && skip !== void 0 && skip.pullDataFromResponse)) interceptors.push(pullDataFromResponse);
  return createPipe(interceptors);
};
var handleUnauthorizedErrorResponse = function handleUnauthorizedErrorResponse(error) {
  var _error$response2, _error$config2;
  if (((_error$response2 = error.response) === null || _error$response2 === void 0 ? void 0 : _error$response2.status) !== 401) return error;
  v2_utils_axios.resetAuthTokens();
  var _ref2 = (_error$config2 = error.config) !== null && _error$config2 !== void 0 ? _error$config2 : {},
    _ref2$redirectOnError = _ref2.redirectOnError,
    redirectOnError = _ref2$redirectOnError === void 0 ? true : _ref2$redirectOnError;
  if (redirectOnError) {
    setTimeout(function () {
      var redirectTo = window.location.pathname === "/login" ? "/login" : "/login?redirect_uri=".concat(encodeURIComponent(window.location.href));

      // eslint-disable-next-line  xss/no-location-href-assign
      window.location.href = redirectTo;
    }, 300);
  }
  return error;
};
var isOnline = function isOnline() {
  return window.navigator.onLine;
};
var showOfflineToastr = function showOfflineToastr() {
  var toastId = neetoAtoms.Toastr.error(i18next.t("neetoCommons.toastr.error.noInternetConnection"));
  if (toastId) {
    var dismissToastInterval = setInterval(function () {
      if (!isOnline()) return;
      reactToastify.toast.dismiss(toastId);
      clearInterval(dismissToastInterval);
      checkOnlineInterval = null;
    }, 1000);
  }
};
var handleNetworkError = function handleNetworkError(error) {
  if (checkOnlineInterval) return error;
  var startTime = Date.now();
  checkOnlineInterval = setInterval(function () {
    var elapsedTime = Date.now() - startTime;
    if (isOnline()) {
      clearInterval(checkOnlineInterval);
      checkOnlineInterval = null;
    } else if (elapsedTime >= v2_initializers_constants.MAXIMUM_OFFLINE_DURATION) {
      clearInterval(checkOnlineInterval);
      showOfflineToastr();
    }
  }, 1000);
  return error;
};
var showErrorToastr = function showErrorToastr(error) {
  var _error$config3, _error$response3;
  var _ref3 = (_error$config3 = error.config) !== null && _error$config3 !== void 0 ? _error$config3 : {},
    _ref3$showToastr = _ref3.showToastr,
    showToastr = _ref3$showToastr === void 0 ? true : _ref3$showToastr,
    _ref3$show422ErrorToa = _ref3.show422ErrorToastr,
    show422ErrorToastr = _ref3$show422ErrorToa === void 0 ? true : _ref3$show422ErrorToa,
    _ref3$url = _ref3.url,
    requestUrl = _ref3$url === void 0 ? "" : _ref3$url,
    _ref3$method = _ref3.method,
    requestMethod = _ref3$method === void 0 ? "" : _ref3$method;
  var _ref4 = (_error$response3 = error.response) !== null && _error$response3 !== void 0 ? _error$response3 : {},
    status = _ref4.status;
  if (!showToastr) return error;
  if (error.message === "Network Error") return handleNetworkError(error);
  if (error.code === "ECONNABORTED") {
    return error;
  }
  var shouldShowToastr = false,
    toastrContent = error;
  var skippedStatusCodes = [403, 404, 520, 422];
  if (!skippedStatusCodes.includes(status) && !axios.isCancel(error)) {
    // we already display a page in case of 403 & 404 and we don't want to show a toastr for cancelled requests.
    // We handle cloudflare error differently for production and other environments.
    shouldShowToastr = true;
  }
  if (status === 422 && show422ErrorToastr) shouldShowToastr = true;
  if (status === 520) {
    shouldShowToastr = true;
    if (globalProps.railsEnv === "production") {
      toastrContent = i18next.t("generic.error");
    }
  }
  if (status === 0) {
    toastrContent = i18next.t("neetoCommons.toastr.error.networkError");
    shouldShowToastr = true;
  }
  var toastIdKey = "".concat(requestMethod, ":").concat(requestUrl);
  var errorToastId = requestErrorToasts[toastIdKey];
  if (errorToastId) reactToastify.toast.dismiss(errorToastId);
  if (shouldShowToastr) {
    if (errorToastId) {
      // if there's an existing toastr with the same message, the onClose callback in the neetoUI which
      // removes the toastr from the unique list will be fired only after the toast is completely removed
      // from the UI. If there's no delay, the new toastr will be considered as duplicate and ignored.
      setTimeout(function () {
        requestErrorToasts[toastIdKey] = neetoAtoms.Toastr.error(toastrContent);
      }, 1200);
    } else requestErrorToasts[toastIdKey] = neetoAtoms.Toastr.error(toastrContent);
  }
  return error;
};
var getUrlPathName = function getUrlPathName(url) {
  try {
    return new URL(url).pathname;
  } catch (_unused) {
    return url;
  }
};
var handle404ErrorResponse = function handle404ErrorResponse(error) {
  var _error$config4, _error$response4;
  var _ref5 = (_error$config4 = error.config) !== null && _error$config4 !== void 0 ? _error$config4 : {},
    _ref5$show404ErrorPag = _ref5.show404ErrorPage,
    show404ErrorPage = _ref5$show404ErrorPag === void 0 ? true : _ref5$show404ErrorPag,
    _ref5$show403ErrorPag = _ref5.show403ErrorPage,
    show403ErrorPage = _ref5$show403ErrorPag === void 0 ? true : _ref5$show403ErrorPag;
  var status = (_error$response4 = error.response) === null || _error$response4 === void 0 ? void 0 : _error$response4.status;
  if (status === 404 && show404ErrorPage || status === 403 && show403ErrorPage) {
    var _error$request;
    var fullUrl = ((_error$request = error.request) === null || _error$request === void 0 ? void 0 : _error$request.responseURL) || error.config.url;
    v2_reactUtils_useDisplayErrorPage_useDisplayErrorPage.useErrorDisplayStore.setState({
      showErrorPage: true,
      statusCode: status,
      failedApiUrl: fullUrl,
      failedApiPath: getUrlPathName(fullUrl)
    });
  }
  return error;
};
var buildErrorResponseHandler = function buildErrorResponseHandler(skip) {
  var interceptors = [];
  if (!(skip !== null && skip !== void 0 && skip.transformCase)) interceptors.push(transformErrorKeysToCamelCase);
  if (!(skip !== null && skip !== void 0 && skip.show404ErrorPage)) interceptors.push(handle404ErrorResponse);
  if (!(skip !== null && skip !== void 0 && skip.logoutOn401)) interceptors.push(handleUnauthorizedErrorResponse);
  if (!(skip !== null && skip !== void 0 && skip.showToastr)) interceptors.push(showErrorToastr);
  if (!(skip !== null && skip !== void 0 && skip.checkForReleaseVersionMismatch)) {
    interceptors.push(checkForReleaseVersionMismatch);
  }
  interceptors.push(Promise.reject.bind(Promise));
  return createPipe(interceptors);
};
var cleanupCredentialsForCrossOrigin = function cleanupCredentialsForCrossOrigin(request) {
  if (!request.url.includes("://")) return request;
  if (request.url.includes(window.location.hostname)) return request;
  return ramda.evolve({
    headers: ramda.omit([v2_initializers_constants.HEADERS_KEYS.xCsrfToken])
  })(request);
};
var transformDataToSnakeCase = function transformDataToSnakeCase(request) {
  var _request$transformReq = request.transformRequestCase,
    transformRequestCase = _request$transformReq === void 0 ? true : _request$transformReq;
  if (!transformRequestCase) return request;
  return ramda.evolve({
    data: neetoCist.serializeKeysToSnakeCase,
    params: neetoCist.serializeKeysToSnakeCase
  }, request);
};
var addRequestInterceptors = function addRequestInterceptors(skip) {
  if (!(skip !== null && skip !== void 0 && skip.cleanCredentialsForCrossOrigin)) {
    axios.interceptors.request.use(cleanupCredentialsForCrossOrigin);
  }
  if (!(skip !== null && skip !== void 0 && skip.transformCase)) {
    axios.interceptors.request.use(transformDataToSnakeCase);
  }
};
var addResponseInterceptors = function addResponseInterceptors(skip) {
  axios.interceptors.response.use(buildSuccessResponseHandler(skip), buildErrorResponseHandler(skip));
};
var registerIntercepts = function registerIntercepts(skip) {
  if (shouldNot(skip === null || skip === void 0 ? void 0 : skip.request)) addRequestInterceptors(skip === null || skip === void 0 ? void 0 : skip.request);
  if (shouldNot(skip === null || skip === void 0 ? void 0 : skip.response)) addResponseInterceptors(skip === null || skip === void 0 ? void 0 : skip.response);
};
function initializeAxios(skip) {
  if (!(skip !== null && skip !== void 0 && skip.baseURL)) axios.defaults.baseURL = "/";
  if (!(skip !== null && skip !== void 0 && skip.authHeaders)) setAuthHeaders();
  if (!(skip !== null && skip !== void 0 && skip.paramsSerializer)) v2_initializers_axiosInitializer_paramsSerializer();
  if (shouldNot(skip === null || skip === void 0 ? void 0 : skip.interceptors)) registerIntercepts(skip === null || skip === void 0 ? void 0 : skip.interceptors);
}

module.exports = initializeAxios;
//# sourceMappingURL=index.js.map
