"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.score = void 0;

var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));

var _debug = _interopRequireDefault(require("debug"));

function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }

function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { (0, _defineProperty2["default"])(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }

var log = (0, _debug["default"])('@pie-lib:categorize:scoring');

var getWeightingRules = function getWeightingRules(scoring) {
  if (!scoring || !scoring.weighting) {
    return [];
  } else {
    if (!scoring.weighting.enabled) {
      return [];
    } else {
      var rules = scoring.weighting ? scoring.weighting.rules || [] : [];
      return rules;
    }
  }
};

var getPartialRulesForCategory = function getPartialRulesForCategory(partial, categoryId) {
  log('partial? ', partial);

  if (!partial || !partial.enabled) {
    return;
  } else {
    var pr = partial.rules.find(function (pr) {
      return pr.category === categoryId;
    });
    return pr ? pr.rules || [] : [];
  }
};
/**
 *
 * Calculate score based on the categories model generated from `buildState` and the partial scoring rules.
 * @param {*} categories - this is the categories that you get from `buildState`.
 * @param {*} scoring  - scoring config.
 * @see ../index#buildState
 */


var score = function score(categories, scoring) {
  return new Promise(function (resolve) {
    log('categories: ', categories, 'scoring: ', scoring);
    var weightingRules = getWeightingRules(scoring);
    var weights = categories.map(function (c) {
      var r = weightingRules.find(function (r) {
        return r.category === c.id;
      }) || {
        points: 1
      };
      return _objectSpread(_objectSpread({}, r), {}, {
        category: c.id
      });
    });
    log('weights: ', weights);
    var weightTotal = categories.reduce(function (total, c) {
      var r = weights.find(function (r) {
        return r.category === c.id;
      });
      return total += r.points;
    }, 0);
    log('total: ', weightTotal);
    var withScore = categories.map(function (c) {
      var w = weights.find(function (r) {
        return r.category === c.id;
      }).points;
      log('category: ', c);

      if (c.correct === true) {
        return {
          category: c.id,
          score: w,
          points: w
        };
      } else {
        var rules = getPartialRulesForCategory(scoring.partial, c.id);
        log('partial rules for category: ', rules);

        if (!rules) {
          return {
            category: c.id,
            score: 0,
            points: w
          };
        } else {
          var correctCount = (c.choices || []).filter(function (h) {
            return h.correct;
          }).length;
          log('correctCount: ', correctCount);
          var rule = rules.find(function (u) {
            return u.count === correctCount;
          });
          log('rule: ', rule);
          rule = rule || {
            percent: 0,
            count: correctCount
          };

          var _score = w * (rule.percent / 100);

          return {
            category: c.id,
            score: _score,
            points: w,
            partial: {
              correctChoices: correctCount,
              rule: rule
            }
          };
        }
      }
    });
    var weightedScore = withScore.reduce(function (sum, c) {
      return sum += c.score;
    }, 0);
    log('weightedScore: ', weightedScore);
    var score = parseFloat((weightedScore / weightTotal).toFixed(2), 10);
    resolve({
      score: score,
      details: {
        weighted: {
          total: weightTotal,
          score: weightedScore
        },
        categories: withScore
      }
    });
  });
};

exports.score = score;
//# sourceMappingURL=scoring.js.map