/* globals window */
import computed from 'ember-computed';
import Component from 'ember-component';
import run from 'ember-runloop';
import injectService from 'ember-service/inject';

const CAROUSEL_SELECTOR = '.carousel__slider';
const CAROUSEL_MENU = '.carousel__menu';
const CAROUSEL_BUTTON_SELECTOR = '.carousel__nav button';
const CAROUSEL_NAV_HEIGHT = 90;
const CAROUSEL_PADDING = 20;


export default Component.extend({
  playerRemoteControl: injectService(),
  classNames: ['carousel', 'flex', 'flex--column', 'flex--nowrap', 'flex--stretch'],

  media: null, // Required, Array of media to be displayed in the carousel

  itemWidth: 160,
  nextVisible: false,
  prevVisible: false,
  slider: null,

  actions: {
    pausePlayer() {
      this.get('playerRemoteControl').pause();
    }
  },

  showArrows: computed.or('nextVisible', 'prevVisible'),

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

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

  didReceiveAttrs() {
    this._setSizes();
  },

  _setSizes() {
    // Only set sizes if we've instantiated our flex slider
    if (this.$('.flex-viewport')) {
      let { carouselWidth, carouselHeight} =
        this.getProperties('carouselWidth', 'carouselHeight');

      // While the main viewer has a more standard 16:9 ratio.
      let naturalViewerHeight = carouselWidth * 9 / 16;
      let maxViewerHeight = carouselHeight - CAROUSEL_NAV_HEIGHT - (CAROUSEL_PADDING * 2);
      let viewerHeight = Math.floor(Math.min(naturalViewerHeight, maxViewerHeight));
      let viewerWidth = viewerHeight * 16 / 9;

      this.$().width(carouselWidth).height(carouselHeight);
      this.$(`${CAROUSEL_SELECTOR} > .flex-viewport`).width(viewerWidth).height(viewerHeight);
      this.debounceTask('_inferGridSize', 100);
    }
  },

  _inferGridSize() {
    let slider = this.slider;
    if (slider) {
      this.slider.resize();
      this.set('prevVisible', slider.paging > 1 && slider.currentSlide > 0);
      this.set('nextVisible', slider.pagingCount > 1 && slider.currentSlide !== slider.last);

      this._updateNav(slider);
    } else {
      this.debounceTask('_inferGridSize', 100);
    }
  },

  _setupFlexbox() {
    let customDirectionNav = this.$(CAROUSEL_BUTTON_SELECTOR);

    this.$(CAROUSEL_SELECTOR).flexslider({
      animation: 'slide',
      controlNav: true,
      directionNav: false,
      animationLoop: false,
      slideshow: false,
      sync: CAROUSEL_MENU
    });

    this.$(CAROUSEL_MENU).flexslider({
      animation: 'slide',
      controlNav: true,
      animationLoop: true,
      customDirectionNav: customDirectionNav,
      slideshow: false,
      itemWidth: this.get('itemWidth'),
      itemMargin: 20,
      asNavFor: CAROUSEL_SELECTOR,
      start: (slider) => {
        this.slider = slider;
        run(this, this._updateNav, slider);
      },
      before: (slider) => {
        run(this, this._updateNav, slider);
      }
    });
    this._setSizes();
  },

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

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

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

  _isPrevVisible(slider) {
    this.set('prevVisible', slider.pagingCount > 1 && slider.animatingTo !== 0);

    let $prev = this.$('.flex-prev');
    if ($prev) {
      $prev[0].disabled = !this.get('prevVisible');
    }
  },

  _isNextVisible(slider) {
    this.set('nextVisible', slider.pagingCount > 1 && slider.animatingTo !== slider.last);

    let $next = this.$('.flex-next');
    if ($next) {
      $next[0].disabled = !this.get('nextVisible');
    }
  }
});
