/* globals window */
import Mixin from 'ember-metal/mixin';
import computed from 'ember-computed';
import run from 'ember-runloop';
import injectService from 'ember-service/inject';
import observer from 'ember-metal/observer';
import limitForDirectoryTower from 'web-client/utilities/tower';
import { CHANNEL_PREVIEW_MIN_WIDTH } from 'web-client/services/layout';
import ContextBoundTasksMixin from 'web-client/mixins/context-bound-tasks';

export default Mixin.create(ContextBoundTasksMixin, {
  layout: injectService(),

  carouselSelector: null,
  carouselButtonSelector: null,

  itemWidth: 210, // default value will change later
  nextVisible: false,
  prevVisible: false,
  slider: null,

  streamsPerRow: limitForDirectoryTower({
    minWidth: CHANNEL_PREVIEW_MIN_WIDTH
  }),

  showArrows: computed('nextVisible', 'prevVisible', function() {
    return this.get('nextVisible') || this.get('prevVisible');
  }),

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

    this.$customDirectionNav = this.$(this.get('carouselButtonSelector'));
    this.$carouselSelector = this.$(this.get('carouselSelector'));

    run.scheduleOnce('afterRender', this, '_setupFlexbox');
  },

  resizeObserver: observer('layout.contentWidth', function() {
    this.debounceTask('_inferGridSize', 100);
  }),

  _inferGridSize() {
    let streamsPerRow = this.get('streamsPerRow');
    let slider = this.slider;

    slider.vars.minItems = streamsPerRow;
    slider.vars.maxItems = streamsPerRow;

    this.runTask(() => this.slider.resize());

    if (slider.pagingCount > 1 && slider.currentSlide > 0) {
      this.set('prevVisible', true);
    } else {
      this.set('prevVisible', false);
    }
    if (slider.pagingCount > 1 && slider.currentSlide !== slider.last) {
      this.set('nextVisible', true);
    } else {
      this.set('nextVisible', false);
    }

    this._updateNav(slider);
  },

  _setupFlexbox() {
    let itemWidth = this.get('itemWidth');
    let streamsPerRow = this.get('streamsPerRow');

    // We're using `controlNav: true` to combat a flexslider bug described here.
    // https://github.com/woothemes/FlexSlider/issues/630

    this.$carouselSelector.flexslider({
      animation: 'slide',
      animationLoop: false,
      itemWidth: itemWidth,
      itemMargin: 20,
      slideshow: false,
      keyboard: false,
      controlNav: true,
      customDirectionNav: this.$customDirectionNav,
      minItems: streamsPerRow,
      maxItems: streamsPerRow,
      start: (slider) => {
        this.slider = slider;
        run(this, this._updateNav, slider);
      },
      before: (slider) => {
        run(this, this._updateNav, slider);
      }
    });
  },

  willDestroyElement() {
    this._super(...arguments);
    this.$carouselSelector.flexslider('destroy');
  },

  _updateNav(slider) {
    if (this.isDestroyed) { return; }

    this._isPrevVisible(slider);
    this._isNextVisible(slider);
  },

  _isPrevVisible(slider) {
    if (slider.pagingCount > 1 && slider.animatingTo !== 0) {
      this.set('prevVisible', true);
    } else {
      this.set('prevVisible', false);
    }
    let $prev = this.$('.flex-prev');
    if ($prev) {
      $prev[0].disabled = !this.get('prevVisible');
    }
  },

  _isNextVisible(slider) {
    if (slider.pagingCount > 1 && slider.animatingTo !== slider.last) {
      this.set('nextVisible', true);
    } else {
      this.set('nextVisible', false);
    }
    let $next = this.$('.flex-next');
    if ($next) {
      $next[0].disabled = !this.get('nextVisible');
    }
  }
});
