const Net = (function () {
  async function sendJsonRequest({ method, url, data, headers }) {
    if (typeof data !== "string") {
      data = JSON.stringify(data);
    }
    if (!headers) headers = {};
    headers["Content-Type"] = "application/json";
    return sendRequest({ method, url, data, headers });
  }

  async function sendRequest({ method, url, data, headers, queryParams }) {
    if (queryParams) {
      let params = new URLSearchParams();
      for (var queryParam in queryParams) {
        params.append(queryParam, queryParams[queryParam]);
      }
      let queryString = params.toString();
      queryString = queryString ? "?" + queryString : "";
      url = url + queryString;
    }
    return new Promise((resolve, reject) => {
      let xhr = new XMLHttpRequest();

      xhr.addEventListener("load", function () {
        resolve({ status: xhr.status, data: xhr.response });
      });

      xhr.addEventListener("readystatechange", function () {
        if (xhr.readyState === XMLHttpRequest.DONE) {
          resolve({ status: xhr.status, data: xhr.response });
        }
      });

      xhr.addEventListener("error", function () {
        reject(xhr.response);
      });

      xhr.open(method, url, true);
      for (var header in headers) {
        xhr.setRequestHeader(header, headers[header]);
      }

      try {
        xhr.send(data);
      } catch (error) {
        reject(error);
      }
    });
  }

  function buildUrl({ protocol, hostname, port, uri }) {
    protocol = protocol || location.protocol;
    hostname = hostname || location.hostname;
    port = port || location.port;
    uri = uri || location.uri;
    return `${protocol}//${hostname}:${port}${uri}`;
  }

  return {
    sendJsonRequest,
    sendRequest,
    buildUrl,
  };
})();

export default Net;
