class Resizer {
  
    static resizeAndRotateImage(
      image: CanvasImageSource,
      size: number,
      compressFormat = "jpeg",
      quality = 100,
      rotation = 0
    ) {
      var qualityDecimal = quality / 100;
      var canvas = document.createElement("canvas");

      canvas.width = size;
      canvas.height = size;
  
      var ctx = canvas.getContext("2d");
      if (ctx) {
      ctx.fillStyle = "rgba(0, 0, 0, 0)";
      ctx.fillRect(0, 0, size, size);
  
      if (ctx.imageSmoothingEnabled && ctx.imageSmoothingQuality) {
        ctx.imageSmoothingQuality = 'high';
      }
  
      if (rotation) {
        ctx.rotate((rotation * Math.PI) / 180);
        if (rotation === 90) {
          ctx.translate(0, -canvas.width);
        } else if (rotation === 180) {
          ctx.translate(-canvas.width, -canvas.height);
        } else if (rotation === 270) {
          ctx.translate(-canvas.height, 0);
        } else if (rotation === 0 || rotation === 360) {
          ctx.translate(0, 0);
        }
      }
      //Вставка картинки. Определяем k в который уменьшилась большая сторона и уменьшаем в него другую сторону
      let width = Number(image.width);
      let height = Number(image.height);
      let Xoffset = 0
      let Yoffset = 0
      const larger = Math.max(width, height)
      const k = Number((larger/size).toFixed(2))
      if (height > width) {
        height = size
        width = Math.round(width / k)
        Xoffset = Math.round((size - width) / 2)
      } else {
        height = Math.round(width / k)
        width = size
        Yoffset = Math.round((size - height) / 2)
      }


      ctx.drawImage(image, Xoffset, Yoffset, width, height);
  
      return canvas.toDataURL(`image/${compressFormat}`, qualityDecimal);
      } else {
        throw new Error
      }
    }
  
    static b64toByteArrays(b64Data:any, contentType:string) {
      contentType = contentType || "image/jpeg";
      var sliceSize = 512;
  
      var byteCharacters = atob(
        b64Data.toString().replace(/^data:image\/(png|jpeg|jpg|webp);base64,/, "")
      );
      var byteArrays = [];
  
      for (var offset = 0; offset < byteCharacters.length; offset += sliceSize) {
        var slice = byteCharacters.slice(offset, offset + sliceSize);
  
        var byteNumbers = new Array(slice.length);
        for (var i = 0; i < slice.length; i++) {
          byteNumbers[i] = slice.charCodeAt(i);
        }
  
        var byteArray = new Uint8Array(byteNumbers);
  
        byteArrays.push(byteArray);
      }
      return byteArrays;
    }
  
    static b64toBlob(b64Data:any, contentType:string) {
      const byteArrays = this.b64toByteArrays(b64Data, contentType);
      var blob = new Blob(byteArrays, { type: contentType});
      return blob;
    }
  
    static b64toFile(b64Data:string, fileName:string, contentType:string) {
      const byteArrays = this.b64toByteArrays(b64Data, contentType);
      const file = new File(byteArrays, fileName, { type: contentType});
      return file;
    }
  
    static createResizedImage(
      file: File,
      size: number,
      compressFormat: string,
      quality: number,
      rotation: number,
      responseUriFunc: any,
      outputType = "base64",
    ) {
      const reader = new FileReader();
      if (file) {
        if (file.type && !file.type.includes("image")) {
          throw Error("File Is NOT Image!");
        } else {
          reader.readAsDataURL(file);
          reader.onload = () => {
            var image = new Image();
            //@ts-ignore
            image.src = reader.result;
            image.onload = function () {
              var resizedDataUrl = Resizer.resizeAndRotateImage(
                image,
                size,
                compressFormat,
                quality,
                rotation
              );
              const contentType = `image/${compressFormat}`;
              switch (outputType) {
                case "blob":
                  const blob = Resizer.b64toBlob(resizedDataUrl, contentType);
                  responseUriFunc(blob);
                break;
                case "base64":
                  responseUriFunc(resizedDataUrl);
                break;
                case "file":
                  let fileName = file.name;
                  let fileNameWithoutFormat = fileName.toString().replace(/(png|jpeg|jpg|webp)$/i, "");
                  let newFileName = fileNameWithoutFormat.concat(compressFormat.toString());
                  const newFile = Resizer.b64toFile(resizedDataUrl, newFileName, contentType);
                  responseUriFunc(newFile);
                break;
                default:
                  responseUriFunc(resizedDataUrl);
              }
            };
          };
          reader.onerror = (error:any
          ) => {
            throw Error(error);
          };
        }
      } else {
        throw Error("File Not Found!");
      }
    }
  }
  export default {
    imageFileResizer: (
      file: File,
      size: number,
      compressFormat: string,
      quality: number,
      rotation: number,
      responseUriFunc: any,
      outputType: string,
    ) => {
      return Resizer.createResizedImage(
        file,
        size,
        compressFormat,
        quality,
        rotation,
        responseUriFunc,
        outputType,
      );
    },
  };