import Component from 'ember-component';
import env from 'web-client/config/environment';
import injectService from 'ember-service/inject';
import moment from 'moment';
import run from 'ember-runloop';

const DEFAULT_STREAM_STATS_CONFIG = {
  showViewers: true,
  showUptime: true,
  showViews: true,
  showFollowers: true,
  showSubs: true,
  showClips: true
};

const STAT_KEY_VALUE_MAP = {
  showViewers: 'viewers_value',
  showUptime: 'uptime_value',
  showViews: 'views_value',
  showFollowers: 'followers_value',
  showSubs: 'subscriptions_value',
  showClips: 'clips_value'
};

export default Component.extend({
  classNames: ['js-dashboard-stream-stats'],

  api: injectService(),
  storage: injectService(),
  subscriptions: injectService(),

  /* passed in properties */
  channel: null,
  isLive: null,
  trackDashboardEvent() {},

  /* internal properties */
  streamStatsConfig: null,
  subscribers: 0,
  clips: 0,
  timeLive: '0:00',

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

    let streamStatsConfig;

    try {
      streamStatsConfig = JSON.parse(this.get('storage.streamStatsConfiguration'));
      streamStatsConfig = streamStatsConfig || DEFAULT_STREAM_STATS_CONFIG;
    } catch(e) {
      streamStatsConfig = DEFAULT_STREAM_STATS_CONFIG;
    } finally {
      this.set('streamStatsConfig', streamStatsConfig);
    }

    this.pollTask(next => {
      if (this.get('isDestroyed') || this.get('isDestroying')) { return; }

      this._retrieveSubscribers();

      if (this.get('isLive')) {
        this._reloadStream();
        this._retrieveClips();
      }

      this.runTask(next, env.delay.dashboard.pollInterval);
    });
  },

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

    this._retrieveSubscribers();

    if (this.get('isLive')) {
      this._reloadStream();
      this._retrieveClips();
    }
  },


  actions: {
    updateStreamStatsConfig(statKey) {
      this.toggleProperty(`streamStatsConfig.${ statKey }`);
      this.set('storage.streamStatsConfiguration', JSON.stringify(this.get('streamStatsConfig')));

      let trackDashboardEvent = this.get('trackDashboardEvent');

      trackDashboardEvent('live_dashboard_stream_stats', {
        action: 'click',
        target_name: STAT_KEY_VALUE_MAP[statKey],
        stats_configuration: this.get('storage.streamStatsConfiguration')
      });
    },

    onHover(targetName) {
      run.throttle(this, this.get('trackDashboardEvent'), 'live_dashboard_stream_stats', {
        action: 'hover',
        target_name: targetName,
        stats_configuration: this.get('storage.streamStatsConfiguration') || JSON.stringify(DEFAULT_STREAM_STATS_CONFIG)
      }, 3000);
    }
  },

  _reloadStream() {
    // reload the stream to get latest number of viewers
    this.get('channel.stream').then(stream => {
      if (this.isDestroyed) { return; }

      stream.reload().then(reloadedStream => {
        if (this.isDestroyed) { return; }

        let timeLiveMs = moment().diff(reloadedStream.get('createdAt'));
        timeLiveMs = timeLiveMs < 0 ? 0 : timeLiveMs;

        let timeLiveHours = Math.floor(moment.duration(timeLiveMs).asHours());
        let timeLiveMinutes = moment.duration(timeLiveMs).minutes() > 9 ? moment.duration(timeLiveMs).minutes() : `0${ moment.duration(timeLiveMs).minutes() }`;
        let timeLive = `${ timeLiveHours }:${ timeLiveMinutes }`;
        this.set('timeLive', timeLive);
      });
    });
  },

  _retrieveSubscribers() {
    let channelLogin = this.get('channel.id');
    let subscriptions = this.get('subscriptions');

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

    subscriptions.getSubscriberCount({ channelLogin })
      .then(res => {
        if (this.isDestroyed) { return; }

        if (res.count) {
          this.set('subscribers', res.count);
        }
      })
      .catch(() => {
        if (this.isDestroyed) { return; }
      });
  },

  _retrieveClips() {
    let broadcastId = this.get('channel.stream._id');
    let api = this.get('api');
    let clipsUrl = `/kraken/broadcasts/${ broadcastId }/clips/count`;

    if (broadcastId) {
      api.request('get', clipsUrl)
      .then(res => {
        if (this.isDestroyed) { return; }

        if (res.count) {
          this.set('clips', res.count);
        }
      });
    }
  }
});
