/* globals Twitch */
import Component from 'ember-component';
import computed from 'ember-computed';
import $ from 'jquery';

export default Component.extend({
  createHighlight() {},
  firstPage: false,
  isCreatingHighlight: false,
  model: null,
  next() {},
  playerComponent: null,
  previous() {},

  didInsertElement() {
    this._super(...arguments);
    this._initHighlightSelector();
  },

  _initHighlightSelector() {
    let markers = {
      left: $('.js-highlighter-handle--left'),
      right: $('.js-highlighter-handle--right')
    };
    let markerContainers = {
      left: $('.js-highlighter-handles__contain--left'),
      right: $('.js-highlighter-handles__contain--right')
    };
    let input = {
      startTime: $('input.start-time'),
      endTime: $('input.end-time')
    };
    let time = {
      startTime: 0,
      endTime: 0
    };
    let selectedMarkerWidthFraction = { left: 0, right: 1 };
    let timeToolTip = $('.js-highlighter-time-tooltip');

    // bind drag events
    markers.left.dragEvents();
    markers.right.dragEvents();

    let seek = (fraction) => {
      let videoLength = this.get('model.length');
      let playerComponent = this.get('playerComponent');

      playerComponent.setCurrentTime(videoLength * fraction);
      if (playerComponent.getPaused()) {
        playerComponent.play();
      }
    };

    // bind seek events
    let markerContainer = $('.js-highlighter-handles');
    this.addEventListener(markerContainer, 'click', (e) => {
      if (!$(e.target).is('.js-highlighter-handle')) {
        seek((e.clientX - markerContainer.offset().left) / markerContainer.width());
      }
    });

    let bindMarkerEvents = (side) => {
      let dragstartWidthFraction;
      let fraction = {};
      let otherSide = side === 'left' ? 'right' : 'left';

      this.addEventListener(markers[side], 'drag', (e, delta) => {
        let videoWidth = $('.js-highlighter-handles').width();
        let deltaWidthFraction = delta.x / videoWidth;

        fraction[side] = dragstartWidthFraction + deltaWidthFraction;
        fraction[otherSide] = selectedMarkerWidthFraction[otherSide];

        setHighlightMarker(fraction.left, fraction.right);
        setTimeInput(time.startTime, time.endTime);
      });

      this.addEventListener(markers[side], 'dragstart', () => {
        dragstartWidthFraction = selectedMarkerWidthFraction[side];
      });

      this.addEventListener(markers[side], 'dragstop', () => {
        seek(fraction[side]);
      });

      // time tooltip tipsy events
      markers[side].tipsy({ gravity: 's', trigger: 'manual' });

      this.addEventListener(markers[side], 'drag mousemove mouseover', () => {
        // remove tipsy outside the marker
        timeToolTip.tipsy('hide');

        markers[side].tipsy('show');
      });

      this.addEventListener(markers[side], 'mouseout dragstop', () => {
        markers[side].tipsy('hide');
      });
    };

    bindMarkerEvents('left');
    bindMarkerEvents('right');

    let setHighlightMarker = (startWidthFraction, endWidthFraction) => {
      let videoLength = this.get('model.length');

      startWidthFraction = Math.min(Math.max(startWidthFraction, 0), 1);
      endWidthFraction = Math.min(Math.max(endWidthFraction, 0), 1);

      // protect bounds
      if (startWidthFraction > endWidthFraction) {
        if (startWidthFraction === selectedMarkerWidthFraction.left) {
          startWidthFraction = endWidthFraction;
        } else {
          endWidthFraction = startWidthFraction;
        }
      }

      let leftWidth = `${startWidthFraction * 100}%`;
      let rightWidth = `${(1 - endWidthFraction) * 100}%`;

      markerContainers.left.css('width', leftWidth);
      markerContainers.right.css('width', rightWidth);

      selectedMarkerWidthFraction.left = startWidthFraction;
      selectedMarkerWidthFraction.right = endWidthFraction;

      let startLength = startWidthFraction * videoLength;
      let endLength = endWidthFraction * videoLength;

      time.startTime = Twitch.display.lengthAsClock(startLength);
      time.endTime = Twitch.display.lengthAsClock(endLength);

      markers.left.attr('title', time.startTime);
      markers.right.attr('title', time.endTime);
    };

    let bindTimeInputEvents = (type) => {
      let videoLength = this.get('model.length');

      this.addEventListener(input[type], 'change', () => {
        let startLength = Twitch.display.clockAsLength(input.startTime.val());
        let endLength = Twitch.display.clockAsLength(input.endTime.val());

        if (startLength > endLength) {
          endLength = startLength;

          input.endTime.val(Twitch.display.lengthAsClock(endLength));
        }

        let startFraction = (startLength || 0) / videoLength;
        let endFraction = (endLength || videoLength) / videoLength;
        setHighlightMarker(startFraction, endFraction);

        this.setProperties({
          'model.startTime': input.startTime.val(),
          'model.endTime': input.endTime.val()
        });
      });
    };

    let setTimeInput = (startTime, endTime) => {
      input.startTime.val(startTime);
      input.endTime.val(endTime);

      this.setProperties({
        'model.startTime': startTime,
        'model.endTime': endTime
      });
    };

    let bindTimeToolTips = () => {
      let highlightMarker = $('.js-highlighter-handles');
      let videoLength = this.get('model.length');

      timeToolTip.tipsy({ gravity: 's', trigger: 'manual' });

      this.addEventListener(highlightMarker, 'mousemove', (e) => {
        let x = e.clientX - highlightMarker.offset().left;
        let fraction = x / highlightMarker.width();
        let displayTime = Twitch.display.lengthAsClock(fraction * videoLength);

        timeToolTip.css({ left: x }).attr('title', displayTime);

        if (!$(e.target).is('.js-highlighter-handle')) {
          timeToolTip.tipsy('show');
        }
      });

      this.addEventListener(highlightMarker, 'mouseout', () => {
        timeToolTip.tipsy('hide');
      });
    };

    setHighlightMarker(0.15, 0.85);
    setTimeInput(time.startTime, time.endTime);
    bindTimeInputEvents('startTime');
    bindTimeInputEvents('endTime');
    bindTimeToolTips();
  },

  startTimeInSeconds: computed('model.startTime', function() {
    return Twitch.display.clockAsLength(this.get('model.startTime') || '');
  }),

  endTimeInSeconds: computed('model.endTime', function() {
    return Twitch.display.clockAsLength(this.get('model.endTime') || '');
  }),

  highlightLength: computed('model.startTime', 'model.endTime', 'endTimeInSeconds', 'startTimeInSeconds', function() {
    if (this.get('model.startTime') && this.get('model.endTime')) {
      return Twitch.display.lengthAsClock(this.get('endTimeInSeconds') - this.get('startTimeInSeconds'));
    }

    return '';
  }),

  actions: {
    usePlayheadTimeStart() {
      let currentTime = this.get('playerComponent').getCurrentTime();
      let time = Twitch.display.lengthAsClock(currentTime);
      this.$('input.start-time').val(time).change();
    },

    usePlayheadTimeEnd() {
      let currentTime = this.get('playerComponent').getCurrentTime();
      let time = Twitch.display.lengthAsClock(currentTime);
      this.$('input.end-time').val(time).change();
    }
  }
});
