import cloneDeep from 'clone-deep';
import { isObjectFull, isDefined } from '../../internal/type-checks.mjs';

function filterRuleSet(ruleset, options) {
  return transformRuleSet(ruleset, (rule) => {
    if (isDefined(rule.field)) {
      if (isDefined(options.excludeFields) && options.excludeFields.includes(rule.field)) {
        return;
      }
      if (isDefined(options.includeFields) && !options.includeFields.includes(rule.field)) {
        return;
      }
      return rule;
    }
  });
}
function renameRuleSetFields(ruleset, replacements) {
  return transformRuleSet(ruleset, (rule) => {
    if (isDefined(rule.field)) {
      rule.field = rule.field in replacements ? replacements[rule.field] : rule.field;
      return rule;
    }
  });
}
function transformRuleSet(ruleSet, transformFn, clone = true) {
  if (clone) {
    ruleSet = cloneDeep(ruleSet);
  }
  ruleSet.rules = ruleSet.rules.map((r) => {
    if (isRule(r)) {
      return transformFn(r);
    } else if (isRuleSet(r)) {
      return transformRuleSet(r, transformFn, false);
    }
  }).filter(isRuleOrRuleset);
  return ruleSet;
}
function countRuleSet(ruleset) {
  const activeFilters = (ruleSet) => {
    let count = 0;
    for (const rule of ruleSet.rules) {
      if (isRule(rule) && rule.field && rule.enabled) {
        count += 1;
      } else if (isRuleSet(rule)) {
        count += activeFilters(rule);
      }
    }
    return count;
  };
  return activeFilters(ruleset);
}
const isRule = (r) => isObjectFull(r) && "field" in r;
const isRuleSet = (r) => isObjectFull(r) && "rules" in r;
const isRuleOrRuleset = (r) => isRule(r) || isRuleSet(r);

export { countRuleSet, filterRuleSet, isRule, isRuleOrRuleset, isRuleSet, renameRuleSetFields, transformRuleSet };
