import {
  DATA_PREVIEW,
} from './constants';
import {
  each,
  empty,
  extend,
  getData,
  getTransforms,
  removeData,
  setData,
  setStyle,
} from './utilities';

export default {
  initPreview() {
    const { crossOrigin } = this;
    const { preview } = this.options;
    const url = crossOrigin ? this.crossOriginUrl : this.url;
    const image = document.createElement('img');

    if (crossOrigin) {
      image.crossOrigin = crossOrigin;
    }

    image.src = url;
    this.viewBox.appendChild(image);
    this.image2 = image;

    if (!preview) {
      return;
    }

    const previews = preview.querySelector ? [preview] : document.querySelectorAll(preview);

    this.previews = previews;

    each(previews, (element) => {
      const img = document.createElement('img');

      // Save the original size for recover
      setData(element, DATA_PREVIEW, {
        width: element.offsetWidth,
        height: element.offsetHeight,
        html: element.innerHTML,
      });

      if (crossOrigin) {
        img.crossOrigin = crossOrigin;
      }

      img.src = url;

      /**
       * Override img element styles
       * Add `display:block` to avoid margin top issue
       * Add `height:auto` to override `height` attribute on IE8
       * (Occur only when margin-top <= -height)
       */
      img.style.cssText = (
        'display:block;' +
        'width:100%;' +
        'height:auto;' +
        'min-width:0!important;' +
        'min-height:0!important;' +
        'max-width:none!important;' +
        'max-height:none!important;' +
        'image-orientation:0deg!important;"'
      );

      empty(element);
      element.appendChild(img);
    });
  },

  resetPreview() {
    each(this.previews, (element) => {
      const data = getData(element, DATA_PREVIEW);

      setStyle(element, {
        width: data.width,
        height: data.height,
      });

      element.innerHTML = data.html;
      removeData(element, DATA_PREVIEW);
    });
  },

  preview() {
    const { imageData, canvasData, cropBoxData } = this;
    const { width: cropBoxWidth, height: cropBoxHeight } = cropBoxData;
    const { width, height } = imageData;
    const left = cropBoxData.left - canvasData.left - imageData.left;
    const top = cropBoxData.top - canvasData.top - imageData.top;

    if (!this.cropped || this.disabled) {
      return;
    }

    setStyle(this.image2, extend({
      width,
      height,
    }, getTransforms(extend({
      translateX: -left,
      translateY: -top,
    }, imageData))));

    each(this.previews, (element) => {
      const data = getData(element, DATA_PREVIEW);
      const originalWidth = data.width;
      const originalHeight = data.height;
      let newWidth = originalWidth;
      let newHeight = originalHeight;
      let ratio = 1;

      if (cropBoxWidth) {
        ratio = originalWidth / cropBoxWidth;
        newHeight = cropBoxHeight * ratio;
      }

      if (cropBoxHeight && newHeight > originalHeight) {
        ratio = originalHeight / cropBoxHeight;
        newWidth = cropBoxWidth * ratio;
        newHeight = originalHeight;
      }

      setStyle(element, {
        width: newWidth,
        height: newHeight,
      });

      setStyle(element.getElementsByTagName('img')[0], extend({
        width: width * ratio,
        height: height * ratio,
      }, getTransforms(extend({
        translateX: -left * ratio,
        translateY: -top * ratio,
      }, imageData))));
    });
  },
};
