import computed from 'ember-computed';
import injectService from 'ember-service/inject';
import AjaxService from 'ember-ajax/services/ajax';
import RSVP from 'rsvp';
import { assign } from 'ember-platform';

const JSONP_OPTIONS = {
  global: false,
  dataType: 'jsonp',
  data: {}
};

const CORS_OPTIONS = {
  global: false,
  dataType: 'json',
  headers: {},
  xhrFields: {}
};

export default AjaxService.extend({
  session: injectService(),

  isCrossOriginEnabled: computed(function() {
    return 'XMLHttpRequest' in window &&
      'withCredentials' in new XMLHttpRequest();
  }),

  // ember-ajax only uses headers if host matches trustedHosts,
  // and we want to add auth headers for all twitch hosts.
  trustedHosts: [ /\.twitch.tv/ ],
  headers: computed('isCrossOriginEnabled', {
    get() {
      let headers = {};

      if (this.get('isCrossOriginEnabled')) {
        headers.Authorization = `OAuth ${this.get('session.userData.chat_oauth_token')}`;
      }

      return headers;
    }
  }),

  _optionsForJSONP(_options) {
    let token = this.get('session.userData.chat_oauth_token');
    let options = {};

    assign(options, JSONP_OPTIONS);
    assign(options, _options);

    // jscs:disable requireCamelCaseOrUpperCaseIdentifiers
    options.data.oauth_token = options.data.oauth_token || token;
    // jscs:enable requireCamelCaseOrUpperCaseIdentifiers
    return options;
  },

  _optionsForCORS(_options) {
    let options = {};

    assign(options, CORS_OPTIONS);
    assign(options, _options);

    options.xhrFields.withCredentials = options.xhrFields.withCredentials || false;
    return options;
  },

  request(url, options={}) {
    if (this.get('isCrossOriginEnabled')) {
      options = this._optionsForCORS(options);
    } else {
      options = this._optionsForJSONP(options);
    }

    if (typeof(options.data) === 'object') {
      options.data = JSON.stringify(options.data);
    }

    return this._super(url, options);
  },

  _request(url, options) {
    if (this.isDestroyed || this.isDestroying) {
      return RSVP.reject();
    }
    return this.request(url, options);
  }
});
