/* jshint bitwise:false, onecase:true, expr:true */
/* globals URI, Twitch */

import $ from 'jquery';
import Controller from 'ember-controller';
import computed from 'ember-computed';
import injectService from 'ember-service/inject';
import injectController from 'ember-controller/inject';
import observer from 'ember-metal/observer';
import { htmlSafe } from 'ember-string';
import ContextBoundTasksMixin from 'web-client/mixins/context-bound-tasks';
import { ROUTES, routeMatches } from 'web-client/utilities/route-matcher';
import { redirectToMobileWeb } from 'web-client/utilities/redirect';

const MOBILE_AGENTS = /(iPad|iPhone|iPod|Android|IEMobile|Windows Phone)/g;
const GAMEDIR_OR_CSGO = /directory\.game|directory\.csgo/;
const CREATIVE_DIR = /directory\.creative\./;

const MOBILE_OPTIMIZED_ROUTES = [
  ROUTES.CHANNEL_PAGE,
  ROUTES.DIRECTORY_ALL_CHANNELS,
  ROUTES.DIRECTORY_CREATIVE,
  ROUTES.DIRECTORY_GAME,
  ROUTES.DIRECTORY_GAMES,
  ROUTES.INDEX,
  ROUTES.USER_VOD
];

const MOBILE_UPSELL_ROUTES = [
  ROUTES.CHANNEL_ANY
];

const SOCIAL_COLUMN_DISABLED_ROUTES = [
  ROUTES.DASHBOARD_PAGE,
  ROUTES.INDEX
];

export default Controller.extend(ContextBoundTasksMixin, {
  globals: injectService(),
  ads: injectService(),
  disableFollowingDirectory: computed.alias('globals.disableFollowingDirectory'),
  useHashLocation: computed.alias('globals.useHashLocation'),

  layout: injectService(),
  session: injectService(),
  persistentPlayer: injectService(),
  settings: injectService('chatSettings'),
  gameDirectory: injectController('directory/game'),
  channel: injectController(),

  experiments: injectService(),
  // NOTICE: The login service is deprecated, plesase use the session service.
  // See app/services/SESSION.md for more details.
  login: injectService(),

  directoryGamesController: injectController('directory/games'),

  playerStyle: computed('layout.playerStyle', function() {
    let playerStyle = this.get('layout.playerStyle');

    return htmlSafe(playerStyle);
  }),

  currentPath: '',

  redirectToMobileWeb,

  init: function () {
    this._super(...arguments);
    this.get('ads');  // the service is lazily injected so we need to force this for the observer.
  },

  currentPathChanged: observer('currentPath', function () {
    let globals = this.get('globals');
    let useHashLocation = this.get('useHashLocation');

    this.runTask(() => {
      let page;
      if (useHashLocation) {
        page = window.location.hash.substring(1);
      } else {
        page = window.location.pathname;
      }
      if (this.get("currentPath") !== "loading") {
        Twitch.tracking.gaq.trackVirtualPageView(page);
        Twitch.tracking.mixpanel.trackDiscovery();
        Twitch.tracking.mixpanel.trackGameClick();
        Twitch.tracking.sendGermanBeacons();
      }
    });

    globals.set('currentPath', this.get('currentPath'));

    // leaving this in for now as a shim, we can remove after
    // tracking.js in web doesn't reference window.App and
    // instead looks up variables on the globals service object
    window.App.set('currentPath', this.get('currentPath'));
  }),

  checkForMobileRoute: observer('currentPath', function () {
    let isMobile = this.isMobileExperienceTarget();
    let isMobileUpsellTarget = this.isMobileUpsellTarget();
    let transitionRoute = this.get('currentPath');
    let hasMobileOptimizedRoute = routeMatches(transitionRoute, MOBILE_OPTIMIZED_ROUTES);
    let hasUpsellRoute = routeMatches(transitionRoute, MOBILE_UPSELL_ROUTES);
    let isMobileExperienceReady = isMobile && hasMobileOptimizedRoute;
    let hasBackedOutOfMobileExperience = !isMobile && hasMobileOptimizedRoute;
    if (isMobileExperienceReady) {
      this.runTask(this.redirectToMobileWeb.bind(this));
    }
    // Specifically guard against overlapping experiences. For example, if the user lands on
    // the channel page and opts out of mobile we do not want to then push them through an upsell
    // route, we just want to give them the channel page.
    if (!hasBackedOutOfMobileExperience && isMobileUpsellTarget && hasUpsellRoute) {
      this.runTask(this.redirectToMobileWeb.bind(this));
    }
  }),

  checkWhetherHideColumn: observer('currentPath', function() {
    let transitionRoute = this.get('currentPath');

    // Handle edge case of left nav on dashboard pages
    if (!this.get('layout.isSocialColumnEnabled') && routeMatches(transitionRoute, [ROUTES.DASHBOARD_PAGE])) {
      return this.set('layout.hideColumns', false);
    }

    if (transitionRoute !== 'loading') {
      let isSocialColumnDisabled = routeMatches(transitionRoute, SOCIAL_COLUMN_DISABLED_ROUTES);
      this.set('layout.hideColumns', isSocialColumnDisabled);
    }
  }),

  isConversationsEnabled: computed.readOnly('login.isLoggedIn'),

  scrollToTop: function () {
    $('#main_col .tse-scroll-content').scrollTop(0);
  },

  _isMobile: function () {
    let agent = navigator.userAgent || '';
    return !!agent.match(MOBILE_AGENTS);
  },

  isMobileExperienceTarget: function () {
    let optedOut = document.cookie.match(/\bmobile_opt_out=true\b/);
    return this._isMobile() && !optedOut;
  },

  isMobileUpsellTarget: function () {
    let optedOut = document.cookie.match(/\bupsell_opt_out=true\b/);
    return this._isMobile() && !optedOut;
  },

  showAds: observer('currentPath', 'ads.enabled', function () {
    this.runTask(() => {
      this._setSitePageType();
      this._setDfpCurrentGameId();
      this._setDfpCurrentChannel();
      this._setDfpPageType();
      this._setDfpCampaign();

      let sitePageType = this.get('sitePageType');
      // only fetch ads if it isn't on the channel page
      if (sitePageType !== 'channel' && sitePageType !== 'front_page') {
        let singleOnly = this.get('layout.isRightColumnClosed');

        Twitch.asyncAds.fetchAds({
          singleOnly: singleOnly
        });
      }
      // note: the channel page triggers its own ads from the player view (ugh)
    });
  }),

  _setSitePageType: function () {
    let currentPath = this.get('currentPath');

    if (currentPath.match(/^directory/)) {
      window.SitePageType = 'directory'; // TODO: deprecate this global
    } else if (currentPath === 'index') {
      window.SitePageType = 'front_page';
    } else if (currentPath.match(/channel\.profile/)) {
      window.SitePageType = 'profile';
    } else if (currentPath.match(/^backpack/)) {
      window.SitePageType = 'backpack';
    } else if (currentPath.match(/dashboards/)) {
      window.SitePageType = 'dashboards';
    } else {
      window.SitePageType = 'channel';
    }
    this.set("sitePageType", window.SitePageType);
  },

  _setDfpCurrentGameId: function () {
    let game = '',
        currentPath = this.get('currentPath');
    if (currentPath && currentPath.match(GAMEDIR_OR_CSGO)) {
      game = this.get('gameDirectory.content.id');
      game = game || 'csgo';
    } else if (currentPath && currentPath.match(CREATIVE_DIR)) {
      game = 'Creative';
    }
    Twitch.asyncAds.setMetadata('game', game);
  },

  _setDfpCurrentChannel: function () {
    let chan = '';
    if (this.get('sitePageType') === 'channel') {
      chan = this.get('channel.content.id');
    }
    Twitch.asyncAds.setMetadata('chan', chan);
  },

  _setDfpPageType: function () {
    let dfpPageType = '',
        currentPath = this.get('currentPath'),
        currentPathPieces = currentPath.split('.'),
        currentPath0 = currentPathPieces[0] || '',
        currentPath1 = currentPathPieces[1] || '';
    switch (currentPath0) {
    case 'directory':
      switch (currentPath1) {
      case 'all':
        dfpPageType = 'channels';
        break;
      case 'random':
        dfpPageType = 'channels';
        break;
      case 'following':
        dfpPageType = 'following';
        break;
      case 'videos':
        dfpPageType = 'videos';
        break;
      case 'game':
        dfpPageType = 'games';
        break;
      default: // All Games Directory: /directory
        dfpPageType = 'games';
        break;
      }
      break;
    }
    Twitch.asyncAds.setMetadata('dfpPageType', dfpPageType);
  },

  _setDfpCampaign: function () {
    if (URI().query(true).campaign) {
      Twitch.asyncAds.setMetadata('campaign', URI().query(true).campaign);
    }
  },

  _setEslAdnxsId: function () {
    switch (this.get('sitePageType')) {
    case 'directory':
      window.adnxsId = 1284021;
      break;
    case 'search':
      window.adnxsId = 1284020;
      break;
    case 'front_page':
      window.adnxsId = 1284017;
      break;
    case 'profile':
      // No ads on the profile
      window.adnxsId = '';
      break;
    case 'backpack':
      // No ads in backpack
      window.adnxsId = '';
      break;
    case 'dashboards':
      // No ads in dashboard
      window.adnxsId = '';
      break;
    case 'channel':
      // No ads in channel
      window.adnxsId = '';
      break;
    }
  }
});
