function loadImage(
  name: string,
  url: string,
  onProgress: (loaded: number, total: number) => void = () => {}
): Promise<{ name: string; img: HTMLImageElement }> {
  return new Promise((resolve, reject) => {
    const img = new Image();
    // img.addEventListener('load', () => {
    // 	resolve({name: name, img: img});
    // });
    // img.addEventListener('error', (e) => reject(e));
    // img.src = url;
    const xhr = new XMLHttpRequest();
    xhr.open("GET", url, true);
    xhr.responseType = "arraybuffer";

    xhr.addEventListener("load", () => {
      if (xhr.status === 200) {
        const blob = new Blob([xhr.response]);
        img.addEventListener("load", () => {
          resolve({ name: name, img: img });
        });
        img.addEventListener("error", () => {
          reject("image failed to load");
        });
        img.src = URL.createObjectURL(blob);
      } else {
        reject("failed status: " + xhr.status.toString());
      }
    });

    xhr.addEventListener("progress", (e) => {
      if (e.lengthComputable) {
        onProgress(e.loaded, e.total);
      } else {
        // average image size
        onProgress(0, 8.1 * 1000); // https://www.pingdom.com/blog/new-facts-and-figures-about-image-format-use-on-websites/#:~:text=Average%20image%20size%20per%20format,a%20Web%20page%20on%20average.
      }
    });

    xhr.addEventListener("error", () => {
      reject("Network error or blocked by cors");
    });

    xhr.send();
  });
}



async function loadImages<T extends { [key: string]: string }>(
  images: T,
  onProgress: (loaded: number, total: number) => void = () => {}
): Promise<{ [K in keyof T]: HTMLImageElement }> {
  const loadedNumbers = Object.keys(images).map(() => 0);
  const totalNumbers = Object.keys(images).map(() => 1);

  const imgs = Object.keys(images).map((key, idx) =>
    loadImage(key, images[key], (loaded, total) => {
      // console.log(key, (loaded / total) * 100);
      loadedNumbers[idx] = loaded;
      totalNumbers[idx] = total;
      onProgress(
        loadedNumbers.reduce((a, b) => a + b),
        totalNumbers.reduce((a, b) => a + b)
      );
    })
  );
  const loadedImgs = await Promise.all(imgs);

  const finishedImgs: { [key: string]: HTMLImageElement } = {};

  loadedImgs.forEach(({ name, img }: { name: string; img: HTMLImageElement }) => {
    finishedImgs[name] = img;
  });
  return finishedImgs as unknown as any;
}

export default loadImages;
export { loadImage };
