import * as EXIF from 'exif-js';

/**
 * 以下代码是修复canvas在ios中显示压缩的问题。
 * Detecting vertical squash in loaded image.
 * Fixes a bug which squash image vertically while drawing into canvas for some images.
 * This is a bug in iOS6 devices. This function from https://github.com/stomita/ios-imagefile-megapixel
 *
 */
function detectVerticalSquash(img: HTMLImageElement) {
  // const iw = img.naturalWidth;
  const ih = img.naturalHeight;
  const canvas = document.createElement('canvas');
  const ctx = canvas.getContext('2d')!;
  const data = ctx.getImageData(0, 0, 1, ih).data;
  let sy = 0;
  let ey = ih;
  let py = ih;
  canvas.width = 1;
  canvas.height = ih;

  ctx.drawImage(img, 0, 0);

  // search image edge pixel position in case it is squashed vertically.
  while (py > sy) {
    const alpha = data[(py - 1) * 4 + 3];
    if (alpha === 0) {
      ey = py;
    } else {
      sy = py;
    }
    py = (ey + sy) >> 1;
  }
  const ratio = (py / ih);
  return ratio === 0 ? 1 : ratio;
}

/**
 *  A replacement for context.drawImage
 * (args are for source and destination).
 */
// tslint:disable-next-line: max-line-length
function drawImageIOSFix(ctx: CanvasRenderingContext2D, img: HTMLImageElement, sx: number, sy: number, sw: number, sh: number, dx: number, dy: number, dw: number, dh: number) {
  const vertSquashRatio = detectVerticalSquash(img);
  // Works only if whole image is displayed:
  // ctx.drawImage(img, sx, sy, sw, sh, dx, dy, dw, dh / vertSquashRatio);
  // The following works correct also when only a part of the image is displayed:
  ctx.drawImage(img, sx * vertSquashRatio, sy * vertSquashRatio, sw * vertSquashRatio, sh * vertSquashRatio, dx, dy, dw, dh);
}

function compressImg(file: File | Blob, scaleWidth: number): Promise<[string, Blob] | undefined> {
  return new Promise((resolve, reject) => {
    const hidCanvas = document.createElement('canvas');
    let hidCtx: CanvasRenderingContext2D | null = null;
    let result = '';

    //生成隐藏画布
    if (hidCanvas.getContext) {
      hidCtx = hidCanvas.getContext('2d');
    } else {
      alert('对不起，您的浏览器不支持图片压缩及上传功能，请换个浏览器试试~');
      return;
    }

    const reader = new FileReader();
    const image = new Image();
    reader.readAsDataURL(file);

    image.onload = () => {
      const upImgWidth = image.width;
      const upImgHeight = image.height;
      //获取图像的方位信息
      EXIF.getData(file as any, function() {
        const orientation = parseInt(EXIF.getTag(file, 'Orientation'));
        const ratio = upImgHeight / upImgWidth;
        const scaleHeight = scaleWidth * ratio;
        const afterWidth = scaleWidth < upImgWidth ? scaleWidth : upImgWidth;
        const afterHeight = scaleWidth < upImgWidth ? scaleHeight : upImgHeight;
        let isRotate = false;
    
        if (upImgWidth < 10 || upImgWidth < 10) {
          alert('请不要上传过小的图片');
          resolve(undefined);
          return;
        } else if (hidCtx) {
          // 设置压缩canvas区域高度及宽度
          hidCanvas.setAttribute('width', afterWidth + 'px');
          hidCanvas.setAttribute('height', afterHeight + 'px');
          if (orientation <= 4) {
            if (orientation === 3 || orientation === 4) {
              isRotate = true;
              hidCtx.translate(scaleWidth, scaleHeight);
              hidCtx.rotate(180 * Math.PI / 180);
            }
          } else {
            if (orientation === 5 || orientation === 6) {
              isRotate = true;
              hidCtx.translate(scaleHeight, 0);
              hidCtx.rotate(90 * Math.PI / 180);
            } else if (orientation === 7 || orientation === 8) {
              isRotate = true;
              hidCtx.translate(0, scaleWidth);
              hidCtx.rotate(270 * Math.PI / 180);
            }
          }
  
          // canvas绘制压缩后图片
          drawImageIOSFix(hidCtx, image, 0, 0, upImgWidth, upImgHeight, 0, 0 , afterWidth, afterHeight);
          // 获取压缩后生成的img对象
          result = hidCanvas.toDataURL('image/jpeg');
          // 获取压缩后生成的blob对象
          hidCanvas.toBlob((blob) => {
            if (blob) {
              const useBlob = isRotate || afterWidth !==  upImgWidth;
              resolve([result, useBlob ? blob : file]);
            }
          }, 'image/jpeg', 1);
        }
      });
    };
    reader.onload = (evt) => {
      const target = evt.target as FileReader;
      const srcString = target.result as string;
      //安卓获取的base64数据无信息头，加之
      image.src = srcString.substring(5, 10) !== 'image' ? srcString.replace(/(.{5})/, '$1image/jpeg;') : srcString;
    };
  });
}

export default compressImg;
