'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _keys = require('babel-runtime/core-js/object/keys');

var _keys2 = _interopRequireDefault(_keys);

var _reselect = require('reselect');

var _field_analysis = require('./field_analysis');

var _field_analysis2 = _interopRequireDefault(_field_analysis);

var _flattened_features = require('./flattened_features');

var _flattened_features2 = _interopRequireDefault(_flattened_features);

var _constants = require('../constants');

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function count(o) {
  if (!o) return 0;
  return o.length;
}

// TODO: This would be easier to follow if we did a ranking and sorted by that,
// rather than this complicated logic.

var createCompareFn = function createCompareFn(featureCount) {
  return function (a, b) {
    // If either field appears in less than 80% of features,
    // prefer the field that appears in more features
    var countThreshold = featureCount * 0.8;
    if (a.count < countThreshold || b.count < countThreshold) {
      return b.count - a.count;
    }

    // If one of the values is between 5 & 10, and the other isn't,
    // prefer the one that is.
    var aCountGood = count(a.values) >= 5; // && count(a.values) <= 10
    var bCountGood = count(b.values) >= 5; // && count(b.values) <= 10
    if (aCountGood && !bCountGood) return -1;
    if (bCountGood && !aCountGood) return 1;

    // Prefer boolean fields
    if (a.type === _constants.FIELD_TYPE_BOOLEAN && b.type !== _constants.FIELD_TYPE_BOOLEAN) return -1;
    if (b.type === _constants.FIELD_TYPE_BOOLEAN && a.type !== _constants.FIELD_TYPE_BOOLEAN) return -1;

    // Then prefer text fields
    if (a.type === _constants.FIELD_TYPE_STRING && b.type !== _constants.FIELD_TYPE_STRING) return -1;
    if (b.type === _constants.FIELD_TYPE_STRING && a.type !== _constants.FIELD_TYPE_STRING) return -1;

    // If both are strings, prefer fields with the least number of words
    if (a.type === _constants.FIELD_TYPE_STRING && b.type === _constants.FIELD_TYPE_STRING) {
      return a.wordStats.mean - b.wordStats.mean;
    }

    return 0;
  };
};

/**
 * Return a sorted list of the best fields to use for a filter
 */
var getBestFilterFields = (0, _reselect.createSelector)(_field_analysis2.default, _flattened_features2.default, function (fieldAnalysis, features) {
  var compareFn = createCompareFn(features.length);
  var discreteFields = (0, _keys2.default)(fieldAnalysis.properties).map(function (fieldname) {
    return fieldAnalysis.properties[fieldname];
  }).concat([fieldAnalysis.$type]).filter(function (field) {
    return field.filterType === _constants.FILTER_TYPE_DISCRETE;
  });
  return discreteFields.sort(compareFn);
});

exports.default = getBestFilterFields;
//# sourceMappingURL=best_fields.js.map