var mime = require("mime");

var algo = "AES-CBC";

var initializeButtons = (root) => {
  var buttons = root.querySelectorAll("a[data-download-button]");

  for (let i = 0; i < buttons.length; i++) {
    initialize(buttons[i]);
  }
};

var initialize = (button) => {
  button.addEventListener("click", onClick);
};

var onClick = (e) => download(e.target);

var download = (button) => {
  var keyData = JSON.parse(button.dataset.key),
    ivData = JSON.parse(button.dataset.iv),
    iv = new Uint8Array(ivData),
    urlGenerator = button.dataset.tempUrlGetGenerator,
    hasFilename = "filename" in button.dataset,
    filename = button.dataset.filename,
    labelPreparing = button.dataset.labelPreparing,
    labelReady = button.dataset.labelReady,
    mimeType = button.dataset.mimeType,
    extension = mime.getExtension(mimeType),
    decryptError = "Error while decrypting file",
    fetchError = "Error while fetching file",
    key,
    url;

  button.textContent = labelPreparing;

  window
    .fetch(urlGenerator)
    .then((r) => {
      if (r.ok) {
        return r.json();
      } else {
        throw new Error(
          "error while downloading url " + r.status + " " + r.statusText,
        );
      }
    })
    .then((data) => {
      return window.fetch(data.url);
    })
    .then((response) => {
      if (response.ok) {
        return response.arrayBuffer();
      }
      throw new Error(response.status + response.statusText);
    })
    .then((buffer) => {
      if (keyData.alg !== undefined) {
        return window.crypto.subtle
          .importKey("jwk", keyData, { name: algo, iv: iv }, false, ["decrypt"])
          .then((key) => {
            return window.crypto.subtle.decrypt(
              { name: algo, iv: iv },
              key,
              buffer,
            );
          });
      }
      return Promise.resolve(buffer);
    })
    .then((decrypted) => {
      var blob = new Blob([decrypted], { type: mimeType }),
        url = window.URL.createObjectURL(blob);
      button.href = url;
      button.target = "_blank";
      button.type = mimeType;
      button.textContent = labelReady;
      if (hasFilename) {
        button.download = filename;
        if (extension !== false) {
          button.download = button.download + "." + extension;
        }
      }
      button.removeEventListener("click", onClick);
      button.click();
    })
    .catch((error) => {
      button.textContent = "";
      button.appendChild(
        document.createTextNode("error while handling decrypted file"),
      );
    });
};

window.addEventListener("load", function (e) {
  initializeButtons(e.target);
});

export { initializeButtons, download };
