import computed from 'ember-computed';
import injectService from 'ember-service/inject';
import AjaxService from 'web-client/services/twitch-presence/backend/ajax';
import config from 'web-client/config/environment';
import RSVP from 'rsvp';
import { presenceHost } from 'web-client/utilities/presence-util';
import run from 'ember-runloop';
import on from 'ember-evented/on';

const SECOND_IN_MS = 1000;

export default AjaxService.extend({
  userIdle: injectService(),
  ping: injectService('twitch-presence/backend/ping'),
  presence: injectService('twitch-presence/presence'),

  baseUrl: presenceHost,
  namespace: 'v2',

  latestActivity: null,
  isPolling: false,
  isIdle: computed.readOnly('userIdle.isIdle'),

  request(url, options) {
    return this._super(`${this.get('baseUrl')}/${this.get('namespace')}/${url || ''}`, options);
  },

  initListener: on('init', function () {
    this.get('userIdle').on('idleChanged', isIdle => {
      this._presence = isIdle ? 'idle': 'online';
      let activity = this.get('latestActivity');
      if (!activity) {
        activity = { type: 'none', game: null };
      }
      this.get('ping').setPresence(activity, this._presence);
    });
  }),

  destroyListener: on('willDestroy', function () {
    this.get('userIdle').off('idleChanged');
  }),

  _setPresence(presence) {
    let latestActivity = this.get('latestActivity');
    let sessionId = this.get('presence.sessionId');
    this._request('online', {
      type: 'POST',
      data: {
        session_id: sessionId,
        availability: presence || 'online',
        activity: latestActivity || null
      }
    });
  },

  startPolling() {
    if (this.get('isPolling')) {
      return;
    }
    this.set('isPolling', true);

    this._presence = 'online';

    this.pollTask(next => {
      if (this.get('isPolling') === false) {
        return;
      }
      new RSVP.Promise(resolve => {
        this._lastResolve = resolve;
        this._setPresence(this._presence);
      }).then(timeout => {
        if (this.isDestroyed || this.get('isPolling') === false) {
          return;
        }
        this.runTask(() => {
          if (this.get('isPolling') === false) {
            return;
          }
          this._presence = this.get('isIdle') ? 'idle' : 'online';
          next();
        }, timeout);
      });
    }, 'TwitchPresenceBackendPollingService#startPolling');
  },

  stopPolling() {
    this.set('isPolling', false);
  },

  // Implement the following logic:
  //
  // 4xx - Stop polling.
  // No Poll-Interval header - Retry in 60s.
  // Otherwise - retry at `Poll-Interval`
  //
  handleResponse(status, headers) {
    run.join(() => {
      if (status >= 400 && status < 500) {
        this.stopPolling();
      }

      let timeout = config.delay.presence.pollInterval;

      let serverControlledTimeout = headers['Poll-Interval'];

      if (serverControlledTimeout) {
        timeout = Number(serverControlledTimeout) * SECOND_IN_MS;
      }

      this._lastResolve(timeout);
      this._lastResolve = null;
    });
  }
});
