/* globals i18n */
import Component from 'ember-component';
import computed from 'ember-computed';
import injectService from 'ember-service/inject';
import { ARCHIVE_TYPE_PARAM } from 'web-client/utilities/video/types';
import moment from 'moment';
import withMomentTimezoneData from 'web-client/utilities/with-moment-timezone-data';

const LINK_ACCOUNT_EVENT_CLICKTHROUGH = 'link_account_message_cta_clickthrough';
const LINK_ACCOUNT_EVENT_DISMISS = 'link_account_message_dismissed';
const LINK_ACCOUNT_EVENT_VIEWED = 'link_account_message_viewed';

const LINK_ACCOUNT_MESSAGE_KEY_PREFIX = 'link_account_message_dismissed';
const LINK_ACCOUNT_MESSAGE_FORMAT = i18n('Link your {{platform}} account to become eligible for drops while you watch!');
const RESUME_WATCHING_BANNER = 'RESUME_WATCHING_BANNER';
const STEAM_PLATFORM_ID = 'steam';

export default Component.extend({
  experiments: injectService(),
  session: injectService(),
  storage: injectService(),
  tracking: injectService(),
  vhs: injectService(),
  vodResumeWatching: injectService(),

  didSendLinkMessageEvent: false,
  isLoggedIn: computed.readOnly('session.isAuthenticated'),
  resumeWatchingBannerEnabled: false,
  pastBroadcastsIsLoading: computed.alias('pastBroadcasts.isLoading'),
  recentPastBroadcastResumeTime: null,

  actions: {
    close() {
      this.set('wasLinkMessageDismissed', true);
      this.set('isVisible', false);

      let platformId = this.get('linkPlatformForChannel.id');
      this.get('tracking').trackEvent({
        event: LINK_ACCOUNT_EVENT_DISMISS,
        data: {
          link_account_platform: platformId
        }
      });
    }
  },

  updateAccountLinkStatusForPlatform() {
    let platformId = this.get('linkPlatformForChannel.id');
    if (platformId !== STEAM_PLATFORM_ID) {
      this.get('vhs')
        .isCurrentUserLinkedToPlatform(platformId)
        .then(
          (isLinked) => {
            if (!this.isDestroyed) {
              this.set('isViewerLinked', isLinked);
            }
          });
    } else {
      this.set('isViewerLinked', !!this.get('viewerSteamId'));
    }
  },

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

    if (!this.get('isCurrentTimeSet')) {
      withMomentTimezoneData().then(tz => {
        if (this.isDestroyed) { return; }

        this.set('currentTime', tz(tz.guess()));
      });
    }

    this.updateAccountLinkStatusForPlatform();

    this.get('experiments').getExperimentValue(RESUME_WATCHING_BANNER).then(value => {
      if (!this.isDestroyed) {
        let resumeWatchingBannerEnabled = (value === 'yes');
        this.set('resumeWatchingBannerEnabled', resumeWatchingBannerEnabled);
      }
    });
  },

  didReceiveAttrs() {
    let didSendLinkMessageEvent = this.get('didSendLinkMessageEvent');
    let showAccountLink = this.get('shouldShowLinkMessage');
    let platformId = this.get('linkPlatformForChannel.id');
    if (showAccountLink && !didSendLinkMessageEvent && platformId) {
      this.get('tracking').trackEvent({
        event: LINK_ACCOUNT_EVENT_VIEWED,
        data: {
          link_account_platform: platformId
        }
      });
    }

    this.set('didSendLinkMessageEvent', showAccountLink);

    if (!this.get('resumeWatchingBannerEnabled')) {
      return;
    }

    let vodResumeWatching = this.get('vodResumeWatching');
    let id = this.get('recentPastBroadcast.id');
    let broadcastId = this.get('recentPastBroadcast.broadcast_id');
    vodResumeWatching.getResumeTime(id, broadcastId, ARCHIVE_TYPE_PARAM).then(
      resumeTime => {
        if (this.isDestroyed) { return; }
        this.set('recentPastBroadcastResumeTime', resumeTime);
      });
  },

  linkPlatformForChannel: computed('name', function () {
    return this.get('vhs').getPlatformForChannel(this.get('name'));
  }),

  shouldShowFollowMessage: computed('isLive', 'isLoggedIn', 'shouldShowFirstPastBroadcast', function () {
    return this.get('isLive') && !this.get('isLoggedIn') && !this.get('shouldShowFirstPastBroadcast');
  }),

  shouldShowFirstPastBroadcast: computed('isLiveStatusReady', 'isLive', 'pastBroadcasts.[]', function () {
    return this.get('isLiveStatusReady') && !this.get('isLive') && this.get('pastBroadcasts.content.length') > 0;
  }),

  recentPastBroadcast: computed('pastBroadcasts.[]', function () {
    return this.get('pastBroadcasts.content.0');
  }),

  isChannelLinked: computed('linkPlatformForChannel.id', 'channelSteamId', function () {
    let platformId = this.get('linkPlatformForChannel.id');
    let steamId = this.get('channelSteamId');

    return platformId && (platformId !== STEAM_PLATFORM_ID || !!steamId);
  }),

  isViewerLinked: true,
  isCurrentTimeSet: computed.bool('currentTime'),

  clickthroughEventConfig: computed('linkPlatformForChannel.id', function () {
    let platformId = this.get('linkPlatformForChannel.id');
    let data = { link_account_platform: platformId };

    return {
      event: LINK_ACCOUNT_EVENT_CLICKTHROUGH,
      data
    };
  }),

  linkMessageDismissedKey: computed('linkPlatformForChannel.id', function () {
    let platformId = this.get('linkPlatformForChannel.id');
    if (platformId) {
      return `${LINK_ACCOUNT_MESSAGE_KEY_PREFIX}_${platformId}`;
    }

    return null;
  }),

  wasLinkMessageDismissed: computed('linkMessageDismissedKey', {
    get() {
      let storage = this.get('storage');
      let key = this.get('linkMessageDismissedKey');

      if (!key) { return false; }

      return !!JSON.parse(storage.get(key));
    },
    set(_, value) {
      let storage = this.get('storage');
      let key = this.get('linkMessageDismissedKey');
      let storageValue = JSON.stringify(!!value);

      if (!key) { return; }

      storage.set(key, storageValue);
    }
  }),

  isInLinkAccountUpsellTimeRange: computed('currentTime', 'linkPlatformForChannel.{startTime,endTime}', function () {
    let startTime = this.get('linkPlatformForChannel.startTime');
    let endTime = this.get('linkPlatformForChannel.endTime');

    if (startTime && endTime) {
      let currentTime = this.get('currentTime');
      return currentTime.isBetween(moment.parseZone(startTime), moment.parseZone(endTime));
    }

    return true;
  }),

  shouldShowLinkMessage: computed('wasLinkMessageDismissed', 'shouldShowFirstPastBroadcast', 'isChannelLinked', 'isInLinkAccountUpsellTimeRange', 'isLoggedIn', 'isLive', 'isViewerLinked', function () {
    let wasDismissed = this.get('wasLinkMessageDismissed');
    let shouldShowFirst = this.get('shouldShowFirstPastBroadcast');
    let isViewerLinked = this.get('isViewerLinked');

    if (wasDismissed || shouldShowFirst || isViewerLinked) { return false; }

    let isLoggedIn = this.get('isLoggedIn');
    let isLiveStatusReady = this.get('isLiveStatusReady');
    let isLive = this.get('isLive');
    let isChannelLinked = this.get('isChannelLinked');
    let isInLinkAccountUpsellTimeRange = this.get('isInLinkAccountUpsellTimeRange');

    return isLoggedIn && isLiveStatusReady && isLive && isChannelLinked && isInLinkAccountUpsellTimeRange;
  }),

  isSteamChannel: computed.equal('linkPlatformForChannel.id', STEAM_PLATFORM_ID),

  linkMessageMainText: computed('linkPlatformForChannel.{message,name}', function () {
    let message = this.get('linkPlatformForChannel.message');
    if (message) {
      return i18n(message);
    }

    let name = this.get('linkPlatformForChannel.name');
    if (name) {
      let translatedString = LINK_ACCOUNT_MESSAGE_FORMAT;
      return translatedString.replace('{{platform}}', name);
    }

    return '';
  }),

  bannerHeaderText: computed('name', 'recentPastBroadcastResumeTime', function () {
    let resumeTime = this.get('recentPastBroadcastResumeTime');
    let translatedString;
    if (resumeTime) {
      translatedString = i18n("Continue Watching {{name}}!");
    } else {
      translatedString = i18n("Watch {{name}}'s Last Broadcast!");
    }
    return translatedString.replace('{{name}}', this.get('name'));
  }),

  bannerMainText: computed('recentPastBroadcastResumeTime', function () {
    let resumeTime = this.get('recentPastBroadcastResumeTime');
    let translatedString;
    if (resumeTime) {
      translatedString = i18n('Continue watching the most recent broadcast from {{name}}.');
    } else {
      translatedString = i18n('This channel is offline now, but you can still check out its most recent broadcast.');
    }
    return translatedString.replace('{{name}}', this.get('name'));
  }),

  bannerLastBroadcastTimeText: computed('recentPastBroadcast.{recordedDate}', function () {
    let yesterday = moment().subtract(1, 'days');
    let recordedDate = moment(this.get('recentPastBroadcast.recordedDate'));
    let recordedTime;
    let timeText;
    if(recordedDate.isAfter(yesterday)) {
      recordedTime = recordedDate.fromNow();
      timeText = i18n('Last broadcast {{recordedTime}}');
    } else {
      recordedTime = recordedDate.format('MMM D, YYYY');
      timeText = i18n('Last broadcast on {{recordedTime}}');
    }
    return timeText.replace('{{recordedTime}}', recordedTime);
  })
});
