(function(window) {
  'use strict';

  var close = false;
  var europe = ["AX","DK","EE","FO","FI","GG","IS","IE","JE","IM","LV","LT","NO","SJ","SE","GB","AL","AD","BA","HR","CY","GI","GR","IT","MK","VA","MT","ME","PT","SM","RS","SI","ES","BY","BG","CZ","GE","HU","MD","PL","RO","RU","SK","UA","AT","BE","FR","DE","LI","LU","MC","NL","CH"];
  var cookieDesc = Object.getOwnPropertyDescriptor(Document.prototype, 'cookie') ||
    Object.getOwnPropertyDescriptor(HTMLDocument.prototype, 'cookie');
  var setter = cookieDesc.set;
  var getter = cookieDesc.get;
  var cookiesSet = [];
  var cookiesBlocked = false;

  function recordCookieSet(str) {
    cookiesSet.push(str);
    return true;
  }

  function deleteAllCookies() {
    var cookies = document.cookie.split(/;\s?/);

    for (var i = 0; i < cookies.length; i++) {
        var cookie = cookies[i];
        var eqPos = cookie.indexOf("=");
        var name = eqPos > -1 ? cookie.substr(0, eqPos) : cookie;
        document.cookie = name + "=; expires=Thu, 01 Jan 1970 00:00:00 GMT";
    }
  }

  function blockCookies() {
    Object.defineProperty(document, 'cookie', {
      get: function () { return getter.call(document) },
      set: recordCookieSet,
      configurable: true
    });

    cookiesBlocked = true;
  }

  function restoreCookies() {
    Object.defineProperty(document, 'cookie', {
      get: function () { return getter.call(document) },
      set: function (val) { setter.call(document, val) },
    });

    // Set any cookie set during the enblockening
    cookiesSet.forEach(c => document.cookie = c);
  }

  /**
   * Retrieves the current users IP Address
   * @returns {Promise} resolves with the IP and other intel
   */
  function getIntel() {
    return fetch('https://geoip.internal.commerce.campaignmonitor.com/json/', {
      method: 'GET'
    })
      .then(function(res) {
        return res.json();
      })
      .then(function(data) {
        return data;
      });
  }

  /**
   * Gets the data with the passed name from localStorage
   * @param {String} name - the name of the property
   * @returns {String/Boolean/Number} the contents of the storage
   */
  function getData(name) {
    return localStorage.getItem(name);
  }

  /**
   * Checks if there is relevant data and what it's content are
   * then checks whether the user has accepted or declined
   * and returns the result
   * @param {String} ip - the users current IP
   * @returns {Object} the has accepted result and ip
   */
  function checkData(ip) {
    var url = window.location.href;

    // First check if there is any data stored
    var acceptCookie = getData('_accept_banner');
    var ipCookie = getData('_accept_banner_ip');

    // They accepted the banner previously
    if (acceptCookie) {
      if (acceptCookie === 'accept') {
        Cooki.setAccepted();
        if (cookiesBlocked) restoreCookies();
      }
      else if (acceptCookie === 'decline') Cooki.setDeclined();
      return { showBanner: false, ip: ip };
    }

    // No accept in storage, continue
    return { showBanner: true, ip: ip };
  }

  /**
   * Logs the decision and IP to the server
   * @param {String} choice - 'accept' or 'decline'
   * @param {String} ip - the users current IP
   * @returns {Promise} resolves on successfully sent log
   */
  function addLog(choice, ip) {
    var meta = {
      choice,
      notification: '5b0730c38634460014b7dbbd',
      ip: ip,
      userAgent: navigator.userAgent,
      url: window.location.href
    };

    return fetch('https://cookihq.com/log', {
      method: 'PUT',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(meta)
    })
    .catch(function(e) {
      console.error('An error occurred while trying to ' +
        'record the acceptance of cookies', e);
    });
  }

  /**
   * Adds the HTML elements with styles and event listeners
   * @param {String} ip - the users current IP
   */
  function addNotification(ip, showBanner) {
    var height = 150;

    // Add style tag for additional compatibility
    var styles = document.createElement('style');
    styles.type = 'text/css';
    var css = '.cooki-description p { color: inherit; }';
    if (styles.styleSheet) styles.styleSheet.cssText = css;
    else styles.appendChild(document.createTextNode(css));
    document.body.appendChild(styles);

    // Create the container of the notification
    var container = document.createElement('div');
    container.style.cssText = 'background:#464646;position:fixed;' +
      'left:0px;right:0px;padding:5em 5em 5em 5em;font-family:Arial, Helvetica, sans-serif;' +
      'z-index: 100000;transition: all 0.3s ease-in;';
    container.className= 'cooki-container';

    var description = document.createElement('div');
    description.style.cssText = 'color:#ffffff';
    description.innerHTML = '<p>This website uses cookies so that we can remember you and understand how you use our site. If you do not agree with our use of cookies, please click the decline button below (please note, some site functions may be unavailable if you decline). You can read more about our Privacy and Cookie policies by clicking the More Info button below. Otherwise, you agree to the use of the cookies as they are currently set. Thank you.</p>';
    description.className = 'cooki-description';
    container.appendChild(description);

    var accept = document.createElement('a');
    accept.style.cssText = 'border:0px;display:inline-block;padding:8px 20px;' +
      'background:#c8ff79;border-radius:0.3em;' +
      'color:#000000;cursor:pointer;font-size:1em;' +
      'text-decoration:none;';
    accept.innerHTML = 'Accept';
    accept.className = 'cooki-accept';
    accept.addEventListener('click', function() {
      // Update Height, the screen size could have altered it
      height = container.clientHeight;
      Cooki.callAccepted();
      if (cookiesBlocked) restoreCookies();
      if ('bottom' === 'top') container.style.top = '-' + height + 'px';
      else container.style.bottom = '-' + height + 'px';

      // Set the data for the accept
      localStorage.setItem('_accept_banner', 'accept');
      localStorage.setItem('_accept_banner_ip', ip);

      addLog('accept', ip);
    });
    container.appendChild(accept);

    var decline = document.createElement('a');
    decline.style.cssText = 'border:0px;display:inline-block;padding:8px 20px;' +
      'background:#eaeaea;border-radius:0.3em;' +
      'color:#000000;cursor:pointer;margin-left:10px;' +
      'font-size:1em;text-decoration:none';
    decline.innerHTML = 'Decline';
    decline.className = 'cooki-decline';
    decline.addEventListener('click', function() {
      // Update Height, the screen size could have altered it
      height = container.clientHeight;
      Cooki.callDeclined();
      if ('bottom' === 'top') container.style.top = '-' + height + 'px';
      else container.style.bottom = '-' + height + 'px';

      // Set the data for the accepts
      localStorage.setItem('_accept_banner', 'decline');
      localStorage.setItem('_accept_banner_ip', ip);

      addLog('decline', ip);
    });
    container.appendChild(decline);

    if (true) {
      var info = document.createElement('a');
      info.style.cssText = 'border:0px;display:inline-block;padding:8px 20px;' +
        'background:#eaeaea;border-radius:0.3em;' +
        'color:#000000;cursor:pointer;margin-left:10px;font-size:1em;' +
        'text-decoration:none;';
      info.innerHTML = 'More Info';
      info.setAttribute('href', 'https://rotofugi.com/pages/cookie-policy');
      info.setAttribute('target', '_blank');
      info.className = 'cooki-info';
      container.appendChild(info);
    }

    // Append the notification to the body
    document.body.appendChild(container);
    height = container.clientHeight;

    if ('false' === 'true') {
      var tab = document.createElement('a');
      tab.style.cssText = 'position:absolute;background:#464646;' +
        'display:block;right:30px;padding:5px 10px;color:#ffffff;' +
        'cursor:pointer;';
      tab.innerText = 'Cookie Information' || 'Cookies';
      tab.addEventListener('click', function() {
        if ('bottom' === 'top') container.style.top = '0px';
        else container.style.bottom = '0px';
      });
      container.appendChild(tab);
      var tabHeight = tab.clientHeight;
      if ('bottom' === 'top') {
        tab.style.bottom = '-' + tabHeight + 'px';
        tab.style.borderBottomRightRadius = '5px';
        tab.style.borderBottomLeftRadius = '5px';
      } else  {
        tab.style.top = '-' + tabHeight + 'px';
        tab.style.borderTopRightRadius = '5px';
        tab.style.borderTopLeftRadius = '5px';
      }
    }

    if ('bottom' === 'top') {
      container.style.top = '-' + height + 'px';
      if (showBanner) setTimeout(function() { container.style.top = '0px'; }, 10);
    } else {
      container.style.bottom = '-' + height + 'px';
      if (showBanner) setTimeout(function() { container.style.bottom = '0px'; }, 10);
    }
  }

  function isInEurope(intel) {
    return europe.indexOf(intel.country_code) > -1;
  }

  function CookiAPI() {
    this.acceptListeners = [];
    this.declineListeners = [];
    this.readyListeners = [];
    this.declined = false;
    this.accepted = false;
    this.isInEurope = false;
  }

  CookiAPI.prototype.addAcceptListener = function(listener) {
    this.acceptListeners.push(listener);
  }

  CookiAPI.prototype.removeAcceptListener = function(listener) {
    this.acceptListeners = this.acceptListeners.filter(function(l) {
      return l !== listener;
    });
  }

  CookiAPI.prototype.addDeclineListener = function(listener) {
    this.declineListeners.push(listener);
  }

  CookiAPI.prototype.removeDeclineListener = function(listener) {
    this.declineListeners = this.declineListeners.filter(function(l) {
      return l !== listener;
    });
  }

  CookiAPI.prototype.addReadyListener = function(listener) {
    this.readyListeners.push(listener);
  }

  CookiAPI.prototype.removeReadyListener = function(listener) {
    this.readyListeners = this.readyListeners.filter(function(l) {
      return l !== listener;
    });
  }

  CookiAPI.prototype.setAccepted = function() {
    this.accepted = true;
    this.declined = false;
  }

  CookiAPI.prototype.setDeclined = function() {
    this.accepted = false;
    this.declined = true;

    // Remove all cookies that are currently accessible
    if (
      '' === 'true' ||
      ('' === '' && 'false' === 'true')
    ) deleteAllCookies();
  }

  CookiAPI.prototype.callAccepted = function() {
    this.setAccepted();
    this.acceptListeners.forEach(function(listener) {
      if (listener) listener();
    });
  }

  CookiAPI.prototype.callDeclined = function() {
    this.setDeclined();
    this.declineListeners.forEach(function(listener) {
      if (listener) listener();
    });
  }

  CookiAPI.prototype.ready = function() {
    this.readyListeners.forEach(function(listener) {
      if (listener) listener();
    });
  }

  window.Cooki = new CookiAPI();

  if ('false' === 'true')  blockCookies();

  getIntel()
    .then(function(intel) {
      var result = isInEurope(intel)
      Cooki.isInEurope = result;

      // Check if the notification should be shown (europe)
      if (true) {
        // Check whether the country is in europe
        if (!result) {
          restoreCookies();
          return { showBanner: false, ip: intel.ip, isEurope: result };
        }
        return checkData(intel.ip);
      }

      // Check whether the ip has already been registered
      return checkData(intel.ip);
    })
    .then(function(data) {
      Cooki.ready();
      if (data.isEurope) return;

      // Add the notification
      addNotification(data.ip, data.showBanner);
    })
    .catch(function(e) {
      console.log(e);
      console.error('An error has occurred when adding the cookie notification', e);
    });
})(window);