angular.module("app").service("BackendService", [
  "$http",
  "$q",
  "$rootScope",
  "$injector",
  function ($http, $q, $rootScope, $injector) {
    this.getPromise = function (url, data, method, disableGZIP) {
      var deferred = $q.defer();

      url = (url.indexOf("/") == 0 ? "" : "/") + url;

      //For AlgoWizard modify the URL to address the target node
      url = checkURL(url);

      if (window.top.auth_token) {
        token = window.top.auth_token;
      }else if(window.parent.sqAuthToken){
        token = window.parent.sqAuthToken;
      }


      var req = {
        url: url,
        headers: {
          "sq-auth-token": token,
        }
      };

      if (isNodeRequest(url)) {
        req.headers = {};
        req.withCredentials = false;
      }

      if (method == "POST") {
        req.method = "POST";

        if ((window.parent && window.parent.remoteURL) || disableGZIP) {
          req.data = $.param(data);
          req.headers["Content-Type"] = "application/x-www-form-urlencoded";
        } else {
          req.data = new Blob([pako.gzip($.param(data))]);
          req.headers["Content-Type"] =
            "application/json; charset=x-user-defined-binary";
          req.headers["Content-Encoding"] = "gzip";
        }
      } else {
        req.method = "GET";
        req.params = data;
        req.headers["sq-auth-token"] = token;
        req.paramSerializer = "$httpParamSerializerJQLike";
      }

      console.log(
        "Http request - url: " + url + ", data: ",
        data,
        ", method: " + req.method + ", token: " + token
      );

      $http(req).then(
        function (response) {
          console.log("Http response -", url, response);

          deferred.resolve({
            success: response.data.success,
            error: response.data.error,
            data: response.data,
          });
        },
        function (response) {
          console.log("Http response failed - ", url, response);

          var defaultErrorMsg = translate(
            "Http request failed - url: %s, status code: %d, statusText: %s",
            [url, response.status, response.statusText]
          );
          if (response.status == -1) {
            $rootScope.showError(defaultErrorMsg);
          }

          deferred.resolve({
            success: false,
            error: response.data ? response.data.error : defaultErrorMsg,
            data: response.data || defaultErrorMsg,
          });
        }
      );

      return deferred.promise;
    };

    this.setToken = function (_token) {
      token = _token;
      window.sqAuthToken = _token;
    };

    this.getToken = function () {
      return token;
    };

    this.sendRequest = function (
      url,
      data,
      callback,
      method,
      forceCallback,
      disableGZIP
    ) {
      if (!data) {
        data = {};
      }

      this.getPromise(url, data, method, disableGZIP).then(function (result) {
        if (result.success) {
          if (callback) {
            callback(result.data);
          }
        } else {
          var text = result.error || translate("Unknown communication error");

          if (
            $rootScope.showError &&
            text.indexOf("RecordNotFoundException") == -1
          ) {
            $rootScope.showError(text);
          }

          if (forceCallback && callback) {
            callback(result.data);
          }
        }
      });
    };

    //cannot import L beacause of circular dependency
    function translate(text, params) {
      if (!text) return "";

      var L = $injector.get("L");
      if (L) {
        return L.tsq(text, params);
      } else {
        return text.format(params);
      }
    }

    function checkURL(url) {
      if (
        window.parent &&
        window.parent.requestsPrefix &&
        !isNodeRequest(url)
      ) {
        url = (window.parent.requestsPrefix + url).replace("//", "/");
      }
      if (window.parent && window.parent.remoteURL && shouldSendToNode(url)) {
        return (
          (window.parent && window.parent.remoteURL
            ? window.parent.remoteURL
            : "") + url
        );
      }

      return url;
    }

    function isNodeRequest(url) {
      if (url.indexOf("overview/getOverviewContent") >= 0) return true;
      if (url.indexOf("strategyconfig/print") >= 0) return true;
      if (url.indexOf("tradeanalysis/print") >= 0) return true;
      if (url.indexOf("equitychart/print") >= 0) return true;
      if (url.indexOf("sourcecode/print") >= 0) return true;
      return false;
    }

    function shouldSendToNode(url) {
      if (url.indexOf("/tradelistviews/") == 0) return false;

      switch (url) {
        default:
          return true;
      }
    }

    var instance = this;
    var token;
  },
]);
