/* globals SiteOptions */

import computed from 'ember-computed';
import injectService from 'ember-service/inject';
import Service from 'ember-service';
import { isPresent } from 'ember-utils';
import { BASE_URL } from 'web-client/utilities/urls/communities';

const MATCH_COMMUNITY_NAME = /#\w+/gi;
const VALID_COMMUNITY_NAME = /^[A-Za-z0-9][A-Za-z0-9_]{2,21}$/;

// Convert an array of strings into a hash with a true value
// to speed up searches on long lists
function arrayToMap(arr) {
  return arr.reduce((total, current) => {
    total[current] = true;
    return total;
  }, {});
}

const BANNED_COMMUNITIES = arrayToMap(SiteOptions.creative_banned_tags ? SiteOptions.creative_banned_tags.split(',') : []);
const ACTIVE_COMMUNITIES = arrayToMap(SiteOptions.creative_communities ? SiteOptions.creative_communities.split(',') : []);
const PROMOTED_COMMUNITIES = arrayToMap(SiteOptions.creative_promoted_communities ? SiteOptions.creative_promoted_communities.split(',') : []);
const CREATIVE_MANAGED_GAME = arrayToMap(["music"]);

export default Service.extend({
  store: injectService(),

  isCreativeManagedGame(game) {
    return isPresent(CREATIVE_MANAGED_GAME[game.toLowerCase()]);
  },

  isActiveCommunity(community) {
    return isPresent(ACTIVE_COMMUNITIES[community]);
  },

  isBannedCommunity(name) {
    return isPresent(BANNED_COMMUNITIES[name]);
  },

  isPromotedCommunity(name) {
    return isPresent(PROMOTED_COMMUNITIES[name]);
  },

  promotedCommunities: computed(function () {
    return (SiteOptions.creative_promoted_communities ? SiteOptions.creative_promoted_communities.split(',') : [])
      .map(tag => this.tagToCommunity(tag));
  }),

  // A valid community name is 2-21 aphanumeric and _ characters
  // which has not been banned
  isValidName(name) {
    return VALID_COMMUNITY_NAME.test(name) && !this.isBannedCommunity(name);
  },

  // Return a valid community from provided tag string (if valid)
  tagToCommunity(name) {
    if (!this.isValidName(name)) {
      return null;
    }
    let isCommunity = this.isActiveCommunity(name);
    let isPromoted = this.isPromotedCommunity(name);
    let banner = this.bannerURL(name);
    let thumbnail = this.thumbnailURL(name);
    return this.get('store').createRecord('community', { name, isCommunity, isPromoted, banner, thumbnail });
  },

  bannerURL(name) {
    return `${BASE_URL}/communities/${name}.jpg`;
  },

  thumbnailURL(name) {
    return `${BASE_URL}/communities/${name}-sm.jpg`;
  },

  // Extract Community instances from each valid community tag
  // in the provided string. A str with `#gamedev` will return the
  // community for `gamedev`
  extractFromTags(str) {
    if (typeof(str) !== 'string') {
      return [];
    }
    return (str.toLowerCase().match(MATCH_COMMUNITY_NAME) || [])
      .uniq()
      .map(tag => this.tagToCommunity(tag.slice(1)))
      .compact();
  },

  // Return true if provided str contains the provided community
  hasCommunityTag(community, str) {
    let name = community.get('name');
    return isPresent(this.extractFromTags(str)
      .find(c => c.get('name') === name));
  }
});
