/* globals Twitch */
import injectService from 'ember-service/inject';
import Service from 'ember-service';
import urlParams from 'web-client/utilities/url-params';

let badgesHost = 'badges.twitch.tv',
    forceHost = urlParams.badges_host;

if (forceHost) {
  let HOST_WHITELIST = [ /^badges-staging\.twitch\.tv$/ ];

  let rejected = true;
  for (let i = 0; rejected && i < HOST_WHITELIST.length; i++) {
    if (HOST_WHITELIST[i].test(forceHost)) {
      rejected = false;
      badgesHost = forceHost;
    }
  }

  if (rejected) {
    let error = "Non-whitelisted badges_host";
    console.error(error);
    throw error;
  }
}

const CORS_OPTIONS = {
  dataType: 'json',
  contentType: 'application/json',
  cache: true,
  global: false,
  retryNum: 0
};

export default Service.extend({
  init() {
    this._super(...arguments);
    this.updateGlobalBadges();
  },

  ajax: injectService(),

  badgeCollection: { global: {}, channel: {} },

  getTargetUrl(badgeData) {
    switch (badgeData.click_action) {
      case 'visit_url':
        return badgeData.click_url;
      case 'subscribe_to_channel':
        return `/${this.badgeCollection.channel.broadcasterName}/subscribe?ref=in_chat_subscriber_link`;
      case 'turbo':
        return '/products/turbo?ref=chat_badge';
    }
    return null;
  },

  getBadgesData(badgesTag=[]) {
    // compatibility step to convert old (tmi) badges tag format: {broadcaster: "1", turbo: "1"}
    // to new (im-store) badges tag format: [{id: "broadcaster", version: "1"}, {id: "turbo", version: "1"}]
    // this entire if block can be removed once the tmijs change to using the new format has propagated
    if (badgesTag.constructor !== Array) {
      let badgesTagArray = [];
      let badgeKeys = Object.keys(badgesTag);

      for (let i = 0; i < badgeKeys.length; i++) {
        let badge = {
          id: badgeKeys[i],
          version: badgesTag[badgeKeys[i]]
        };
        badgesTagArray.push(badge);
      }

      badgesTag = badgesTagArray;
    }

    let badges = [];

    for (let i = 0; i < badgesTag.length; i++) {
      let badgeName = badgesTag[i].id;
      let badgeVersion = badgesTag[i].version;
      let badgeData;

      let channelSet = this.badgeCollection.channel[badgeName];
      let globalSet = this.badgeCollection.global[badgeName];

      // Use global as fallback if channel set and/or version doesn't exist
      if (channelSet && badgeVersion in channelSet.versions) {
        badgeData = channelSet.versions[badgeVersion];
      } else if (globalSet && badgeVersion in globalSet.versions) {
        badgeData = globalSet.versions[badgeVersion];
      }

      if (badgeData) {
        let targetUrl = this.getTargetUrl(badgeData);
        let srcSet = '';
        if (badgeData.image_url_2x) {
          srcSet = `${badgeData.image_url_2x} 2x`;
          if (badgeData.image_url_4x) {
            srcSet += `, ${badgeData.image_url_4x} 4x`;
          }
        }
        else if (badgeData.image_url_4x) {
          srcSet = `${badgeData.image_url_4x} 4x`;
        }

        badges.push({
          id: badgeName,
          version: badgeVersion,
          src: badgeData.image_url_1x,
          srcSet: srcSet,
          title: badgeData.title,
          targetUrl: targetUrl
        });
      }
      else {
        console.error('Invalid badge tag provided');
      }
    }

    return badges;
  },

  parseBadgesTag(value) {
    let parsedBadges = [];
    if (!value) {
      return parsedBadges;
    }

    let badgeTags = value.split(',');
    for (let i = 0; i < badgeTags.length; i++) {
      let badgeTag = badgeTags[i];
      let [ badgeName, badgeVersion ] = badgeTag.split('/');
      let parsedBadge = {
        id: badgeName,
        version: badgeVersion
      };
      parsedBadges.push(parsedBadge);
    }

    return parsedBadges;
  },

  requestGlobalBadges(version) {
    if (this.get('_globalBadgePromise')) {
      return this.get('_globalBadgePromise');
    } 

    let languageCode = Twitch.receivedLanguage;
    let badgeSrc = `https://${badgesHost}/v${version}/badges/global/display?language=${languageCode}`;
    let badgePromise = this.get('ajax').request(badgeSrc, CORS_OPTIONS)
      .then(res => res.badge_sets)
      .catch(() => { this.set('_globalBadgePromise', null); });
    
    this.set('_globalBadgePromise', badgePromise);

    return badgePromise;
  },

  updateGlobalBadges(version='1') {
    this.requestGlobalBadges(version).then(badgeSets => {
      badgeSets = badgeSets || {};
      this.set('badgeCollection.global', badgeSets);
    });
  },

  requestChannelBadges(channelId, broadcasterName, version) {
    let channelPromiseName = `_${broadcasterName}BadgePromise`;
    if (this.get(channelPromiseName)) {
      return this.get(channelPromiseName);
    }

    let languageCode = Twitch.receivedLanguage;
    let badgeSrc = `https://${badgesHost}/v${version}/badges/channels/${channelId}/display?language=${languageCode}`;
    
    let badgePromise = this.get('ajax').request(badgeSrc, CORS_OPTIONS)
      .then(res => res.badge_sets)
      .catch(() => { this.set(channelPromiseName, null); });

    this.set(channelPromiseName, badgePromise);
    return badgePromise;
  },

  updateChannelBadges(channelId, broadcasterName, version='1') {
    this.requestChannelBadges(channelId, broadcasterName, version).then(badgeSets => {
      badgeSets = badgeSets || {};
      badgeSets.broadcasterName = broadcasterName;
      this.set('badgeCollection.channel', badgeSets);
    });
  }

});
