import Component from 'ember-component';
import computed from 'ember-computed';
import { assert } from 'ember-metal/utils';
import { htmlSafe } from 'ember-string';

import { readFile, loadImage } from 'web-client/utilities/html5-loader';
import ClickOutsideMixin from 'web-client/mixins/click-outside';
import getFileFromEvent from 'web-client/utilities/get-file-from-event';

export default Component.extend(ClickOutsideMixin, {
  tagName: 'label',
  classNames: ['balloon-wrapper', 'js-sub-badge-image-picker'],

  // TODO: replace inline style with class:
  attributeBindings: ['style'],
  style: computed('file', 'showFileSizeError', 'showImageDimensionError', function () {
    let defaultStyle = 'display: inline-block; vertical-align: top; margin-right: 10px; cursor: pointer; border-width: 2px; border-style: dashed; height: 110px; width: 110px; text-align: center;';
    let borderColor;

    if (this.get('file')) {
      borderColor = 'border-color: #14B866'; // $twitch-green
    } else if (this.get('showFileSizeError') || this.get('showImageDimensionError')) {
      borderColor = 'border-color: #FC3636'; // $twitch-red
    } else {
      borderColor = 'border-color: #bbb';
    }

    return htmlSafe(`${defaultStyle} ${borderColor}`);
  }),

  // Passed-in properties:
  fileSizeLimitBytes: null,
  imageHeightRequirement: null,
  imageWidthRequirement: null,
  inputName: null,
  file: null,
  updateFile: null,

  // Own properties:
  imgSrc: null,
  showBadImageError: false,
  showFileSizeError: false,
  showImageDimensionError: false,

  fileSizeLimitKilobytes: computed('fileSizeLimitBytes', function () {
    let fileSizeLimitBytes = this.get('fileSizeLimitBytes');

    return Math.floor(fileSizeLimitBytes / 1000);
  }),

  imageStyle: computed('file', 'imageHeightRequirement', 'imageWidthRequirement', function () {
    let displayStyle = this.get('file') ? '' : 'display: none;';
    let height = this.get('imageHeightRequirement');
    let width = this.get('imageWidthRequirement');

    return htmlSafe(`margin: auto; height: ${ height }px; width: ${ width }px; ${ displayStyle }`);
  }),

  init() {
    this._super(...arguments);

    let isFileSizeLimitValid = (typeof this.get('fileSizeLimitBytes') === 'number');
    let isImageHeightRequirementValid = (typeof this.get('imageHeightRequirement') === 'number');
    let isImageWidthRequirementValid = (typeof this.get('imageWidthRequirement') === 'number');
    let inputName = this.get('inputName');
    let isInputNameValid = (typeof inputName === 'string') && (inputName.length > 0);
    let isUpdateFileValid = (typeof this.get('updateFile') === 'function');

    assert(`${this} requires valid argument "fileSizeLimitBytes"`, isFileSizeLimitValid);
    assert(`${this} requires valid argument "imageHeightRequirement"`, isImageHeightRequirementValid);
    assert(`${this} requires valid argument "imageWidthRequirement"`, isImageWidthRequirementValid);
    assert(`${this} requires valid argument "inputName"`, isInputNameValid);
    assert(`${this} requires valid argument "updateFile"`, isUpdateFileValid);
  },

  didInsertElement() {
    this._super(...arguments);

    this.$input = this.$('input');

    // remove after updating to 2.10.0
    this.$img = this.$('img');
  },

  didUpdateAttrs() {
    this._super(...arguments);

    if (this.get('file') === null) {
      this.$input.attr('value', null);

      this.set('imgSrc', null);

      // remove after updating to Ember 2.10.0
      // this is needed due to a bug in Ember 2.10.0-beta.3
      // see: https://github.com/emberjs/ember.js/issues/14595
      this.$img.attr('src', null);
    }
  },

  actions: {
    onInputChange(event) {
      let file = getFileFromEvent(event);
      let isOverFileSizeLimit = file.size > this.get('fileSizeLimitBytes');

      this.set('showFileSizeError', isOverFileSizeLimit);

      if (isOverFileSizeLimit) {
        this.$input.attr('value', null);
      } else {
        this._readFile(file);
      }
    }
  },

  clickedOutside() {
    this.set('showBadImageError', false);
    this.set('showFileSizeError', false);
    this.set('showImageDimensionError', false);
  },

  _loadImage(file, readerResult) {
    let heightRequirement = this.get('imageHeightRequirement');
    let widthRequirement = this.get('imageWidthRequirement');
    let updateFile = this.get('updateFile');

    loadImage(readerResult).then(image => {
      if (this.isDestroyed) { return; }

      this.set('showBadImageError', false);

      if ((image.height === heightRequirement) && (image.width === widthRequirement)) {
        this.set('showImageDimensionError', false);
        this.set('imgSrc', readerResult);

        updateFile(file);
      } else {
        this.set('showImageDimensionError', true);
        this.$input.attr('value', null);

        updateFile(null);
      }
    }, error => {
      if (this.isDestroyed) { return; }

      if (error.type !== 'error') {
        throw error;
      }

      this.set('showBadImageError', true);
      this.$input.attr('value', null);

      updateFile(null);
    });
  },

  _readFile(file) {
    readFile(file).then(result => {
      if (this.isDestroyed) { return; }

      return this._loadImage(file, result);
    }, error => {
      if (this.isDestroyed) { return; }

      if (error.type !== 'error') {
        throw error;
      }

      this.set('showBadImageError', true);
    });
  }
});
