/* globals Twitch */

import $ from 'jquery';
import Evented from 'ember-evented';
import Service from 'ember-service';
import computed from 'ember-computed';
import injectService from 'ember-service/inject';
import run from 'ember-runloop';
import observer from 'ember-metal/observer';
import { routeMatches, ROUTES } from 'web-client/utilities/route-matcher';
import urlParams from 'web-client/utilities/url-params';

const LEFT_COLUMN_ANIMATION_TIME = 200;
const PLAYER_ABOVE_HEIGHT = 120;
const PLAYER_BELOW_HEIGHT = 60;
const TARGET_PLAYER_ABOVE_HEIGHT = 94;
const TARGET_PLAYER_BELOW_HEIGHT = 185;
const CONTENT_PADDING = 60;
const RIGHT_COLUMN_WIDTH_OPEN = 340;
const PERSISTENT_PLAYER_HEIGHT = 146;
const PERSISTENT_PLAYER_WIDTH = 260;

const SCROLL_CONTAINER_SELECTOR = '#main_col .tse-scroll-content';

const SHOULD_SHOW_SOCIAL_COLUMN = urlParams.show_sc ? urlParams.show_sc.toLowerCase() : null;

export const TOP_NAV_HEIGHT = 50;
export const LEFT_COLUMN_WIDTH_CLOSED = 50;
export const LEFT_COLUMN_WIDTH_OPEN = 240;
export const SOCIAL_COLUMN_WIDTH_COLLAPSED = 50;
export const SOCIAL_COLUMN_WIDTH_OPEN = 240;
export const CHANNEL_PREVIEW_MIN_WIDTH = 240;
export const GAME_BOX_MIN_WIDTH = 180;
export const PERSISTENT_PLAYER_BOTTOM_MARGIN = 10;
export const PERSISTENT_PLAYER_LEFT_MARGIN = 10;
export const CHANNEL_COVER_HEIGHT = 380;

export default Service.extend(Evented, {
  globals: injectService(),
  // NOTICE: The login service is deprecated, plesase use the session service.
  // See app/services/SESSION.md for more details.
  login: injectService(),
  tracking: injectService(),
  session: injectService(),
  experiments: injectService(),

  bypassApplicationLayout: false,
  hideLocalizedContentSection: false,
  isRightColumnClosedByUserAction: false,
  isLeftColumnClosedByUserAction: false,
  isChatOpenOnProfileSidebar: true,
  isTheatreMode: false,
  showWormholeOverlay: false,
  showRightColumn: false,
  showLeftColumn: true,
  userData: computed.readOnly('login.userData'),
  userDidActivateSearch: false,
  isSubNavExperiment: false,
  isOnsiteNotificationsEnabled: false,
  PLAYER_CONTROLS_HEIGHT: 32,

  init() {
    this._super(...arguments);
    this._readFromLocalStorage();
    this.isLeftColumnAnimating = false;
    if (SHOULD_SHOW_SOCIAL_COLUMN === 'false') {
      Twitch.storage.set('SHOW_SC', false);
    } else if (SHOULD_SHOW_SOCIAL_COLUMN === 'true') {
      Twitch.storage.del('SHOW_SC');
    }

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

    this.get('experiments').getExperimentValue('ONSITE_NOTIFICATIONS').then(value => {
      this.set('isOnsiteNotificationsEnabled', value === 'variant1');
    });
  },

  onLeftColumnToggle: observer('isLeftColumnClosed', function() {
    this.set('isLeftColumnAnimating', true);
    this.debounceTask('_leftColumnDidStopAnimating', LEFT_COLUMN_ANIMATION_TIME);
  }),

  _leftColumnDidStopAnimating() {
    this.set('isLeftColumnAnimating', false);
  },

  isTooSmallForSocialColumn: computed('windowWidth', function () {
    return this.get('windowWidth') < 1201;
  }),

  isTooSmallForLeftColumn: computed('windowWidth', function () {
    return this.get('windowWidth') < 1024;
  }),

  isTooSmallForRightColumn: computed('windowWidth', function () {
    return this.get('windowWidth') < 820;
  }),

  hideColumns: true,

  isLeftColumnClosed: computed('isLeftColumnClosedByUserAction', 'userDidActivateSearch', 'isTooSmallForLeftColumn', function () {
    if (this.get('userDidActivateSearch')) {
      return false;
    }

    return this.get('isTooSmallForLeftColumn') || this.get('isLeftColumnClosedByUserAction');
  }),

  hideLeftColumnExpander: computed('showLeftColumn', 'isTooSmallForLeftColumn', 'hideColumns', function () {
    return this.get('hideColumns') || !this.get('showLeftColumn') || this.get('isTooSmallForLeftColumn');
  }),

  isRightColumnClosed: computed('isRightColumnClosedByUserAction', 'isTooSmallForRightColumn', 'showRightColumn', function () {
    return !this.get('showRightColumn') ||
           this.get('isRightColumnClosedByUserAction') ||
           this.get('isTooSmallForRightColumn');
  }),

  hideRightColumnExpander: computed('showRightColumn', 'isTooSmallForRightColumn', 'hideColumns', function () {
    return this.get('hideColumns') || !this.get('showRightColumn') || this.get('isTooSmallForRightColumn');
  }),

  persistentPlayerDimensions: computed(function() {
    return {
      height: PERSISTENT_PLAYER_HEIGHT,
      width: PERSISTENT_PLAYER_WIDTH,
      targetHeight: PERSISTENT_PLAYER_HEIGHT
    };
  }),

  fullSizePlayerDimensions: computed('contentWidth', 'windowHeight', function() {
    let contentWidth = this.get('contentWidth');
    let naturalPlayerHeight = contentWidth * 9 / 16;
    let maxPlayerHeight = this.get('windowHeight') - PLAYER_ABOVE_HEIGHT - PLAYER_BELOW_HEIGHT;
    let maxTargetPlayerHeight = this.get('windowHeight') - TARGET_PLAYER_ABOVE_HEIGHT - TARGET_PLAYER_BELOW_HEIGHT;
    let playerWidth = Math.floor(contentWidth);
    let playerHeight = Math.floor(Math.min(naturalPlayerHeight, maxPlayerHeight));
    let targetPlayerHeight = Math.floor(Math.min(naturalPlayerHeight, maxTargetPlayerHeight));

    return {
      height: playerHeight,
      width: playerWidth,
      targetHeight: targetPlayerHeight
    };
  }),

  playerStyle: computed('fullSizePlayerDimensions', function () {
    return `<style>
        .dynamic-player, .dynamic-player object, .dynamic-player video{
          width :${this.get('fullSizePlayerDimensions.width')}px !important;
          height:${this.get('fullSizePlayerDimensions.height')}px !important
        }

        .dynamic-target-player,
        .dynamic-target-player object, .dynamic-target-player video {
          width:${this.get('fullSizePlayerDimensions.width')}px !important;
          height:${this.get('fullSizePlayerDimensions.targetHeight')}px !important;
        }

        .dynamic-player .player object, .dynamic-player .player video {
          width:100% !important;
          height:100% !important
        }
      </style>`;
  }),

  isSocialColumnEnabled: computed('session.userData', function() {
    let isStaff = this.get('session.userData.is_staff');
    let isOptedOut = SHOULD_SHOW_SOCIAL_COLUMN === 'false' || Twitch.storage.getObject('SHOW_SC') === false;
    return isStaff && !isOptedOut;
  }),

  contentWidth: computed('windowWidth', 'isRightColumnClosed', 'isLeftColumnClosed', 'isTooSmallForSocialColumn', function () {
    let socialColumnSize = this.get('isTooSmallForSocialColumn') ? SOCIAL_COLUMN_WIDTH_COLLAPSED : SOCIAL_COLUMN_WIDTH_OPEN;
    if (!this.get('isSocialColumnEnabled')) {
      socialColumnSize = 0;
    }
    let rightBarSize = this.get('isRightColumnClosed') ? 0 : RIGHT_COLUMN_WIDTH_OPEN;
    let navBarSize = this.get('isLeftColumnClosed') ? LEFT_COLUMN_WIDTH_CLOSED : LEFT_COLUMN_WIDTH_OPEN;
    if (this.get('isSocialColumnEnabled')){
      navBarSize = 0;
    }

    return this.get('windowWidth') - navBarSize - rightBarSize - CONTENT_PADDING - socialColumnSize;
  }),

  wideEnoughForAds: computed('windowWidth', function () {
    // 1030 comes from contain having 30px of l & r padding, not sure of a better way to calc this.
    // not sure how to consistently get the real width of the ad either, there could be a 768x60 there.
    const MINIMUM_WIDTH_FOR_AD = 1030;
    return this.get('windowWidth') >= MINIMUM_WIDTH_FOR_AD;
  }),

  saveColumnState: observer('isLeftColumnClosedByUserAction', 'isRightColumnClosedByUserAction', function () {
    Twitch.cache.write('Layout', {
      isLeftColumnClosedByUserAction: this.get('isLeftColumnClosedByUserAction'),
      isRightColumnClosedByUserAction: this.get('isRightColumnClosedByUserAction')
    });
  }),

  setChatHeight: observer('isRightColumnClosed', function () {
    run.scheduleOnce('afterRender', this, function () {
      let h = $('.js-new-channel-ad').outerHeight();
      $('.js-rightcol-content').css('top', h);
    });
  }),

  saveHiddenLocalizedContentState: observer('hideLocalizedContentSection', function () {
    Twitch.cache.write('LocalizedContent', {hideLocalizedContentSection: this.get('hideLocalizedContentSection')});
  }),

  _readFromLocalStorage() {
    this.set('isLeftColumnClosedByUserAction', (Twitch.cache.read('Layout') || {}).isLeftColumnClosedByUserAction);
    this.set('isRightColumnClosedByUserAction', (Twitch.cache.read('Layout') || {}).isRightColumnClosedByUserAction);
    this.set('hideLocalizedContentSection', (Twitch.cache.read('LocalizedContent') || {}).hideLocalizedContentSection);
  },

  setTheatreMode(value) {
    this.set('isTheatreMode', value);

    this.get('tracking').trackEvent({
      event: 'theatre_mode',
      data: {
        state: this.get('isTheatreMode') ? 'enabled' : 'disabled'
      }
    });
  },

  hideWormholeOverlay: computed('isTheatreMode', 'showWormholeOverlay', function () {
    return this.get('isTheatreMode') && !this.get('showWormholeOverlay');
  }),

  channelCoverHeight: computed('globals.currentPath', function() {
    let currentPath = this.get('globals.currentPath');
    let isChannelRoute = routeMatches(currentPath, ROUTES.CHANNEL_ANY);

    // temporary solution for the sub-nav experiment, which removes the streamer banner
    // on the channel page
    if (this.get('isSubNavExperiment') && routeMatches(currentPath, ROUTES.CHANNEL)) {
      return 0;
    }

    return isChannelRoute ? CHANNEL_COVER_HEIGHT : 0;
  }),

  setScrollHeight(scrollHeight) {
    let $scrollContainer = $(SCROLL_CONTAINER_SELECTOR);

    if ($scrollContainer.length >= 1) {
      $scrollContainer.scrollTop(scrollHeight);
    }
  },

  scrollTo(scrollHeight) {
    let $scrollContainer = $(SCROLL_CONTAINER_SELECTOR);

    if ($scrollContainer.length >= 1) {
      $scrollContainer.animate({
        scrollTop: scrollHeight
      }, 250);
    }
  },

  resetScroll() {
    this.setScrollHeight(this.get('channelCoverHeight'));
  }
});
