
/**
 * Module dependencies.
 */

var integration = require('analytics.js-integration');
var foldl = require('foldl');
var each = require('each');
var fbq;

/**
 * Expose `Facebook Pixel`.
 */

var FacebookPixel = module.exports = integration('Facebook Pixel')
  .global('fbq')
  .option('pixelId', '')
  .mapping('standardEvents')
  .mapping('legacyEvents')
  .tag('<script src="//connect.facebook.net/en_US/fbevents.js">');

/**
 * Initialize Facebook Pixel.
 *
 * @param {Facade} page
 */

FacebookPixel.prototype.initialize = function(){
  fbq = window.fbq = window._fbq = function() {
    if (fbq.callMethod) {
      fbq.callMethod.apply(fbq, arguments);
    } else {
      fbq.queue.push(arguments);
    }
  };
  fbq.push = fbq;
  fbq.loaded = true;
  fbq.version = '2.0';
  fbq.queue = [];
  this.load(this.ready);
  fbq('init', this.options.pixelId);
};

/**
 * Has the Facebook Pixel library been loaded yet?
 *
 * @return {Boolean}
 */

FacebookPixel.prototype.loaded = function(){
  return !!(fbq && fbq.callMethod);
};

/**
 * Trigger a page view.
 *
 * @param {Facade} identify
 */

FacebookPixel.prototype.page = function(){
  window.fbq('track', 'PageView');
};

/**
 * Track an event.
 *
 * @param {Facade} track
 */

FacebookPixel.prototype.track = function(track){
  var event = track.event();
  var revenue = formatRevenue(track.revenue());

  var payload = foldl(function(acc, val, key) {
    if (key === 'revenue') {
      acc.value = revenue;
      return acc;
    }

    acc[key] = val;
    return acc;
  }, {}, track.properties());

  var standard = this.standardEvents(event);
  var legacy = this.legacyEvents(event);

  // non-mapped events get sent as "custom events" with full
  // tranformed payload
  if (![].concat(standard, legacy).length) {
    window.fbq('trackCustom', event, payload);
    return;
  }

  // standard conversion events, mapped to one of 9 standard events
  // send full transformed payload
  each(function(event) {
    window.fbq('track', event, payload);
  }, standard);

  // legacy conversion events — mapped to specific "pixelId"s
  // send only currency and value
  each(function(event) {
    window.fbq('track', event, {
      currency: track.currency(),
      value: revenue
    });
  }, legacy);
};

/**
 * Viewed product category.
 *
 * @api private
 * @param {Track} track category
 */

FacebookPixel.prototype.viewedProductCategory = function(track) {
  window.fbq('track', 'ViewContent', {
    content_ids: [track.category() || ''],
    content_type: 'product_group'
  });
};

/**
 * Viewed product.
 *
 * @api private
 * @param {Track} track
 */

FacebookPixel.prototype.viewedProduct = function(track) {
  window.fbq('track', 'ViewContent', {
    content_ids: [track.id() || track.sku() || ''],
    content_type: 'product',
    content_name: track.name() || '',
    content_category: track.category() || '',
    currency: track.currency(),
    value: formatRevenue(track.price())
  });
};

/**
 * Added product.
 *
 * @api private
 * @param {Track} track
 */

FacebookPixel.prototype.addedProduct = function(track) {
  window.fbq('track', 'AddToCart', {
    content_ids: [track.id() || track.sku() || ''],
    content_type: 'product',
    content_name: track.name() || '',
    content_category: track.category() || '',
    currency: track.currency(),
    value: formatRevenue(track.price())
  });
};

/**
 * Completed Order.
 *
 * @api private
 * @param {Track} track
 */

FacebookPixel.prototype.completedOrder = function(track) {
  var key;
  var content_ids = foldl(function(acc, product) {
    key = product.id || product.sku;
    if (key) acc.push(key);
    return acc;
  }, [], track.products() || []);

  var revenue = formatRevenue(track.revenue());

  window.fbq('track', 'Purchase', {
    content_ids: content_ids,
    content_type: 'product',
    currency: track.currency(),
    value: revenue
  });
};


/**
 * Get Revenue Formatted Correctly for FB.
 *
 * @api private
 * @param {Track} track
 */

function formatRevenue(revenue) {
  return Number(revenue || 0).toFixed(2);
}

@@ -143,17 +143,8 @@
 h');
-%0Avar fbq;
 %0A%0A/*
@@ -531,14 +531,8 @@
 )%7B%0A 
- fbq =
  win
@@ -576,16 +576,23 @@
     if (
+window.
 fbq.call
@@ -603,24 +603,31 @@
 od) %7B%0A      
+window.
 fbq.callMeth
@@ -635,16 +635,23 @@
 d.apply(
+window.
 fbq, arg
@@ -678,16 +678,23 @@
 %7B%0A      
+window.
 fbq.queu
@@ -721,24 +721,31 @@
    %7D%0A  %7D;%0A  
+window.
 fbq.push = f
@@ -747,15 +747,29 @@
 h = 
-fbq;%0A  
+window.fbq;%0A  window.
 fbq.
@@ -781,24 +781,31 @@
 d = true;%0A  
+window.
 fbq.version 
@@ -815,16 +815,23 @@
 2.0';%0A  
+window.
 fbq.queu
@@ -865,16 +865,23 @@
 ady);%0A  
+window.
 fbq('ini
@@ -1056,15 +1056,29 @@
  !!(
-fbq && 
+window.fbq && window.
 fbq.

use window