/**
 * Get requestAutocomplete data. Can only be called as part of an interaction event
 * listener such as mouse up/down, click, key & touch.
 * 
 * @param  {{billing: boolean, shipping: boolean}} opts
 *   If billing is true, credit card & billing address details will be requested.
 *   If shipping is true, a shipping name & address will be requested.
 * @param  {function(response:Object<string, string>)} callback [description]
 *   You callback is passed a single response object in this format:
 *   {
 *     // May be an empty string (no error), or:
 *     // unsupported - Browser doesn't support requestAutocomplete
 *     // disabled - Browser supports requestAutocomplete but it's disabled or can't be called at this time
 *     // cancel - The user aborted the process
 *     // invalid - Some data may be incorrect/missing
 *     'err': String,
 *     // The retrieved data, may be missing data on err
 *     'data': {
 *       // Card data (if billing data requested)
 *       'cc': {
 *         'name': String,
 *         'number': String,
 *         'exp-month': String,
 *         'exp-year': String,
 *         'csc': String
 *       }
 *       // Billing address data (if billing data requested)
 *       'billing': {
 *         'email': String,
 *         'name': String,
 *         'tel': String,
 *         'address-line1': String,
 *         'address-line2': String,
 *         'locality': String,
 *         'region': String,
 *         'postal-code': String,
 *         'country': String
 *       }
 *       // Shipping data (if requested)
 *       'shipping': {
 *         // same fields as billing
 *       }
 *     }
 *   }
 * @return {void}
 * @example
 *   requestUserData({
 *     billing: true,
 *     shipping: true
 *   }, function(response) {
 *     if (response.err == 'cancel') {
 *       // exit silently
 *       return;
 *     }
 *     if (response.err) {
 *       // fall back to normal form
 *       window.location.href = '/normal-checkout-form/';
 *       return;
 *     }
 *
 *     // send response.data to your server,
 *     // be sure to validate on the server too!
 *     console.log(response.data);
 *   });
 */
function requestUserData(opts, callback) {
  var getBilling = opts.billing;
  var getShipping = opts.shipping;
  var form = document.createElement('form');
  var dataToRequest = [];
  var inputs;
  var addressData = [
    'email',
    'name',
    'tel',
    'address-line1',
    'address-line2',
    'locality',
    'region',
    'postal-code',
    'country'
  ];

  if (!form.requestAutocomplete) {
    callback({
      err: 'unsupported',
      data: {}
    });
    return;
  }

  if (getBilling) {
    dataToRequest.push(
      'cc-name',
      'cc-number',
      'cc-exp-month',
      'cc-exp-year',
      'cc-csc'
    );

    dataToRequest = dataToRequest.concat(addressData.map(function(item) {
      return 'billing ' + item;
    }));
  }

  if (getShipping) {
    dataToRequest = dataToRequest.concat(addressData.map(function(item) {
      return 'shipping ' + item;
    }));
  }

  inputs = dataToRequest.map(function(autocompleteVal) {
    var input = document.createElement('input');
    input.autocomplete = autocompleteVal;
    form.appendChild(input);
    return input;
  });

  function getData() {
    var data = {};

    if (getBilling) {
      data.cc = {};
      data.billing = {};
    }
    if (getShipping) {
      data.shipping = {};
    }

    inputs.forEach(function(input) {
      var type = input.autocomplete;
      if (type.slice(0,2) == 'cc') {
        data.cc[type.slice(3)] = input.value;
      }
      else if (type.slice(0,7) == 'billing') {
        data.billing[type.slice(8)] = input.value;
      }
      else if (type.slice(0,8) == 'shipping') {
        data.shipping[type.slice(9)] = input.value;
      }
    });

    return data;
  }

  form.addEventListener('autocomplete', function() {
    callback({
      data: getData()
    });
  });

  form.addEventListener('autocompleteerror', function(event) {
    callback({
      err: event.reason,
      data: getData()
    });
  });

  form.requestAutocomplete();
}