import Component from 'ember-component';
import computed from 'ember-computed';
import InteractivityDeferredComponent from 'web-client/mixins/interactivity-deferred-component';
import injectService from 'ember-service/inject';
import { htmlSafe } from 'ember-string';
import { PLAYER_ANIMATION_DURATION } from 'web-client/services/persistent-player';
import SendRouteAction from 'web-client/mixins/send-route-action';
import { normalizeVideoId } from 'web-client/utilities/normalize-video-id';

const TRANSITION_STYLE = `all ${PLAYER_ANIMATION_DURATION / 1000}s cubic-bezier(0.215, 0.61, 0.355, 1)`;

const STYLE_STATE_ANIMATION_START = 'animationstart';
const STYLE_STATE_ANIMATING = 'animating';
const STYLE_STATE_THEATRE = 'theatre';
const STYLE_STATE_MINI = 'mini';
const STYLE_STATE_FULLSIZE = 'fullsize';

export default Component.extend(SendRouteAction, InteractivityDeferredComponent, {
  classNames: ['js-player-persistent'],
  attributeBindings: ['style'],
  classNameBindings: [
    'isMini:player-mini',
    'isMini:js-player-mini',
    'playerIsVisible::hidden'
  ],

  persistentPlayer: injectService(),
  persistentPlayerContent: injectService(),
  layout: injectService(),
  experiments: injectService(),

  isPlaying: false,

  pausedByUser: computed.readOnly('persistentPlayer.playerComponent.pausedByUser'),
  playerIsVisible: computed.readOnly('persistentPlayer.isVisible'),
  fullSizePlayerLocation: computed.readOnly('persistentPlayer.fullSizePlayerLocation'),
  animationCoords: computed.readOnly('persistentPlayer.animationCoords'),
  isAnimating: computed.readOnly('persistentPlayer.isAnimating'),
  persistentPlayerLocation: computed.readOnly('persistentPlayer.persistentPlayerLocation'),
  isPreAnimation: computed.readOnly('persistentPlayer.isPreAnimation'),
  playerDimensions: computed.readOnly('persistentPlayer.playerDimensions'),

  currentChannel: computed.readOnly('persistentPlayerContent.currentChannel'),
  targetChannel: computed.readOnly('persistentPlayerContent.targetChannel'),
  isContentHosted: computed.readOnly('persistentPlayerContent.isHosted'),
  currentVOD: computed.readOnly('persistentPlayerContent.currentVOD'),
  currentCollection: computed.readOnly('persistentPlayerContent.currentCollection'),
  canGenerateClips: computed.readOnly('persistentPlayerContent.canGenerateClips'),

  isTheatreMode: computed.readOnly('layout.isTheatreMode'),
  fullSizePlayerDimensions: computed.readOnly('layout.fullSizePlayerDimensions'),
  persistentPlayerDimensions: computed.readOnly('layout.persistentPlayerDimensions'),

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

    this.get('experiments').getExperimentValue('CPR_SUB_NAV_V2').then(value => {
      this.set('isSubNavExperiment', value === 'new');
    });
  },

  didInsertElement() {
    this.set('persistentPlayer.playerElement', this.$());
  },

  willDestroyElement() {
    this.set('persistentPlayer.playerElement', null);
    this.set('persistentPlayer.playerComponent', null);
  },

  styleState: computed('persistentPlayer.isMini', 'isTheatreMode', 'isAnimating', 'isPreAnimation', function() {
    if (this.get('isTheatreMode')) {
      return STYLE_STATE_THEATRE;
    } else if (this.get('isPreAnimation')) {
      return STYLE_STATE_ANIMATION_START;
    } else if (this.get('isAnimating')) {
      return STYLE_STATE_ANIMATING;
    } else if (this.get('persistentPlayer.isMini')) {
      return STYLE_STATE_MINI;
    }

    return STYLE_STATE_FULLSIZE;
  }),

  isMini: computed.equal('styleState', STYLE_STATE_MINI),

  hasMiniControls: computed('styleState', function() {
    let styleState = this.get('styleState');

    return styleState === STYLE_STATE_MINI || styleState === STYLE_STATE_ANIMATING;
  }),

  vodId: computed('currentVOD', function() {
    let currentVOD = this.get('currentVOD');

    if (!currentVOD) {
      return null;
    }

    return `v${normalizeVideoId(currentVOD.get('id'))}`;
  }),

  // The route that the 'expand' player takes you to
  anchorRoute: computed('currentChannel', 'currentVOD', function() {
    let currentVOD = this.get('currentVOD');
    let currentChannel = this.get('currentChannel');

    if (!currentVOD) {
      return {
        route: 'channel.index',
        params: currentChannel.get('name')
      };
    }

    return {
      route: 'videos',
      params: currentVOD
    };
  }),

  style: computed(
    'miniPlayerStyle',
    'fullSizePlayerStyle',
    'animationOriginStyle',
    'animationDestStyle',
    'styleState',
    function() {
      let style;

      switch (this.get('styleState')) {
        case STYLE_STATE_THEATRE:
          style = '';
          break;
        case STYLE_STATE_ANIMATION_START:
          style = this.get('animationOriginStyle');
          break;
        case STYLE_STATE_ANIMATING:
          style = this.get('animationDestStyle');
          break;
        case STYLE_STATE_MINI:
          style = this.get('miniPlayerStyle');
          break;
        default:
          style = this.get('fullSizePlayerStyle');
      }

      return htmlSafe(style);
    }
  ),

  fullSizePlayerStyle: computed('fullSizePlayerDimensions', 'fullSizePlayerLocation', function() {
    let dimensions = this.get('fullSizePlayerDimensions');

    return `
      position: absolute;
      z-index: 2;
      margin-left: 30px;
      margin-right: 30px;
      top: ${this.get('fullSizePlayerLocation.top')}px;
      width :${dimensions.width}px;
      height:${dimensions.height}px;
    `;
  }),

  miniPlayerStyle: computed('persistentPlayerLocation', function() {
    let playerLocation = this.get('persistentPlayerLocation');

    return `
      left: ${playerLocation.left}px;
    `;
  }),

  animationOriginStyle: computed('playerDimensions', 'animationCoords', function() {
    let animationCoords = this.get('animationCoords');
    let playerDimensions = this.get('playerDimensions');

    return `
      position: ${animationCoords.position};
      z-index: 4;
      left: ${animationCoords.originX}px;
      top: ${animationCoords.originY}px;
      height: ${playerDimensions.height}px;
      width: ${playerDimensions.width}px;
      transform-origin: 0px 0px;
    `;
  }),

  animationDestStyle: computed('animationSourceStyle', 'animationCoords', function() {
    let animationCoords = this.get('animationCoords');
    let originStyle = this.get('animationOriginStyle');

    return `
      ${originStyle}
      transition: ${TRANSITION_STYLE};
      transform:
        translateX(${animationCoords.translateX}px)
        translateY(${animationCoords.translateY}px)
        scaleX(${animationCoords.scaleX})
        scaleY(${animationCoords.scaleY});
    `;
  }),

  actions: {
    hideMiniPlayer() {
      this.get('persistentPlayer').trackMiniPlayerAction('close', 'user_minimize');
      this.sendRouteAction('hideMiniPlayer');
    },

    visitHostedChannel() {
      this.get('persistentPlayer').trackMiniPlayerAction('expand', 'user_maximize');
      let name = this.get('currentChannel.hostModeTarget.name');

      this.sendRouteAction('returnToPlayerRoute', 'channel', name);
    },

    setPlayerComponent(playerComponent) {
      this.set('persistentPlayer.playerComponent', playerComponent);
    },

    togglePlay() {
      let playerComponent = this.get('persistentPlayer.playerComponent');
      if (!playerComponent) {
        return;
      }

      if (playerComponent.getPaused() || playerComponent.getEnded())  {
        playerComponent.play();
      } else {
        playerComponent.pause();
        playerComponent.set('userSetPlayerToPause', true);
      }
    },

    anchorPlayer() {
      let { route, params } = this.get('anchorRoute');

      this.get('persistentPlayer').trackMiniPlayerAction('expand', 'user_maximize');
      this.sendRouteAction('returnToPlayerRoute', route, params);
    },

    handleExitFullscreen() {
      if (this.get('isSubNavExperiment')) {
        this.get('layout').setScrollHeight(0);
      } else {
        this.get('layout').resetScroll();
      }
    },

    videoPlayed() {
      this.set('isPlaying', true);
    },

    videoPaused() {
      this.set('isPlaying', false);
    },

    onPersistenceUpdate() {
      this.get('persistentPlayer').syncPersistenceSetting();
    },

    videoPlayerContentShowing() {
      this.reportInteractive();
    }
  }
});
