import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
import _objectSpread from "@babel/runtime/helpers/objectSpread2";
import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties";
import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
var _excluded = ["$and", "$or"];
import { pick } from 'lodash';
import sift from 'sift';
import { typesWithElements, useStatePreferInitial } from './utils'; // const show = (formData, element) => {
//   const rule = element.filter?.show;
//   if (!rule) {
//     return true;
//   }
//   return sift(element.filter.show.query)(formData);
// };

export var isArrayRule = function isArrayRule(rule) {
  return ['$or', '$and'].includes(rule);
};
export var toTarget = function toTarget(element) {
  var _ref5;

  var _ref = (_ref5 = element.filter && Object.values(element.filter)) !== null && _ref5 !== void 0 ? _ref5 : [],
      _ref2 = _slicedToArray(_ref, 1),
      _ref2$ = _ref2[0];

  _ref2$ = _ref2$ === void 0 ? {} : _ref2$;
  var query = _ref2$.query;

  if (query) {
    var $and = query.$and,
        $or = query.$or,
        other = _objectWithoutProperties(query, _excluded);

    var _Object$entries$filte = Object.entries(_objectSpread({
      $and: $and,
      $or: $or
    }, other)).filter(function (_ref3) {
      var _ref4 = _slicedToArray(_ref3, 2),
          rule = _ref4[0],
          value = _ref4[1];

      return isArrayRule(rule) ? value === null || value === void 0 ? void 0 : value.length : value !== undefined;
    }),
        _Object$entries$filte2 = _slicedToArray(_Object$entries$filte, 1),
        _Object$entries$filte3 = _slicedToArray(_Object$entries$filte2[0], 2),
        key = _Object$entries$filte3[0],
        value = _Object$entries$filte3[1];

    return isArrayRule(key) ? Object.keys(value[0])[0] : key;
  }
};

function pageTitleElementOf(elements, element) {
  if (elements.findIndex(function (element) {
    return element.type === 'pageTitle';
  }) === -1) {
    return undefined;
  }

  var findElement = elements.find(function (el) {
    return el.key === element.key;
  }); // eslint-disable-next-line @super-template/no-loops/no-loops

  for (var i = elements.indexOf(findElement) - 1; i >= 0; i--) {
    if (elements[i].type === 'pageTitle') {
      return elements[i];
      break;
    }
  } // If page title was not found, return first page title


  return elements.find(function (element) {
    return element.type === 'pageTitle';
  });
}

function resetDisabledToDefaultValues(formData, initialFormData, config, allDisabled) {
  if (!formData || typeof formData !== 'object') {
    return formData;
  }

  var resetFormData = Array.isArray(formData) ? _toConsumableArray(formData) : _objectSpread({}, formData);

  var _loop = function _loop(key) {
    var _element$filter, _element$elements;

    var element = config.elements.find(function (element) {
      return element.key === key;
    });

    if (allDisabled && (element === null || element === void 0 ? void 0 : element.type) !== 'compose' || (element === null || element === void 0 ? void 0 : (_element$filter = element.filter) === null || _element$filter === void 0 ? void 0 : _element$filter.enable) && !sift(element.filter.enable.query)(formData)) {
      if (initialFormData && initialFormData[key] !== undefined) {
        resetFormData[key] = initialFormData[key];
      } else if (element.elements && element.elements.length > 0) {
        var _formData$key;

        var resetSubValues = resetDisabledToDefaultValues((_formData$key = formData[key]) !== null && _formData$key !== void 0 ? _formData$key : undefined, initialFormData ? initialFormData[key] : undefined, element, true);

        if (!resetSubValues) {
          delete resetFormData[key];
        } else {
          resetFormData[key] = element.list ? [resetSubValues] : resetSubValues;
        }
      } else if (element["default"] !== undefined) {
        if (element.list) {
          resetFormData[key] = Array(element.minItems > 1 ? element.minItems : 1).fill(element["default"]);
        } else {
          resetFormData[key] = element["default"];
        }
      } else {
        delete resetFormData[key];
      }
    } else if ((element === null || element === void 0 ? void 0 : element.elements) && (element === null || element === void 0 ? void 0 : (_element$elements = element.elements) === null || _element$elements === void 0 ? void 0 : _element$elements.length) > 0) {
      if (element.skipDisable) {
        resetFormData[key] = formData[key];
      } else if (element.list) {
        var _formData$key2;

        resetFormData[key] = (_formData$key2 = formData[key]) === null || _formData$key2 === void 0 ? void 0 : _formData$key2.map(function (datum, i) {
          return resetDisabledToDefaultValues(datum !== null && datum !== void 0 ? datum : undefined, (initialFormData === null || initialFormData === void 0 ? void 0 : initialFormData[key]) ? initialFormData[key][i] : undefined, element, false);
        });
      } else {
        var _formData$key3;

        var _resetSubValues = resetDisabledToDefaultValues((_formData$key3 = formData[key]) !== null && _formData$key3 !== void 0 ? _formData$key3 : undefined, initialFormData ? initialFormData[key] : undefined, element, false);

        resetFormData[key] = _resetSubValues;
      }
    }
  };

  for (var key in formData) {
    _loop(key);
  }

  return resetFormData;
}

var getElementIndentation = function getElementIndentation(element, elements) {
  if (element.type === 'pageTitle') {
    return element;
  }

  if (element.list && element.type === 'formGroup') {
    var formGroupElements = element.elements.map(function (el) {
      return getElementIndentation(el, element.elements);
    });
    return _objectSpread(_objectSpread({}, element), {}, {
      elements: formGroupElements,
      indent: getIndentNumber(element, elements),
      listItem: element.list
    });
  }

  return _objectSpread(_objectSpread({}, element), {}, {
    indent: getIndentNumber(element, elements),
    listItem: element.list
  });
};

var getIndentNumber = function getIndentNumber(element, elements) {
  var _element$filter2, _element$filter2$show;

  var query = element === null || element === void 0 ? void 0 : (_element$filter2 = element.filter) === null || _element$filter2 === void 0 ? void 0 : (_element$filter2$show = _element$filter2.show) === null || _element$filter2$show === void 0 ? void 0 : _element$filter2$show.query;

  if (query) {
    var queryKey = Object.keys(query)[0];
    var source = queryKey === '$or' || queryKey === '$and' || queryKey === '$in' ? Object.keys(query[queryKey][0])[0] : queryKey;
    var sourceElement = elements.find(function (element) {
      return element.key === source;
    });

    if (sourceElement && !sourceElement.hidden) {
      return 1 + getIndentNumber(sourceElement, elements);
    }
  }

  return 0;
};

export function dynamicElements(config) {
  var formData = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};

  // config.list element is filtered in ArrayField component.
  if (config.list || !typesWithElements.includes(config.type)) {
    return config;
  }

  var elements = config.elements;
  var checkChanges = true; // eslint-disable-next-line @super-template/no-loops/no-loops

  var _loop2 = function _loop2() {
    var _elements = elements,
        length = _elements.length;
    var keys = elements.map(function (element) {
      return element.key;
    });
    var filteredFormData = pick(formData, keys);
    elements = elements.filter(function test(element) {
      var _element$filter3, _element$filter3$show;

      var query = (_element$filter3 = element.filter) === null || _element$filter3 === void 0 ? void 0 : (_element$filter3$show = _element$filter3.show) === null || _element$filter3$show === void 0 ? void 0 : _element$filter3$show.query;
      var pageTitle = pageTitleElementOf(config.elements, element);

      if (pageTitle !== undefined && element.type !== 'pageTitle' && !elements.includes(pageTitle)) {
        return false;
      }

      if (!query) {
        return true;
      }

      return sift(query)(filteredFormData);
    }).map(function (element) {
      return dynamicElements(element, filteredFormData[element.key]);
    }).map(function (element) {
      return getElementIndentation(element, elements);
    }).map(function (element) {
      var _element$filter4, _element$filter4$enab;

      var query = (_element$filter4 = element.filter) === null || _element$filter4 === void 0 ? void 0 : (_element$filter4$enab = _element$filter4.enable) === null || _element$filter4$enab === void 0 ? void 0 : _element$filter4$enab.query;

      if (!query) {
        return element;
      } else {
        return _objectSpread(_objectSpread({}, element), {}, {
          disabled: !sift(query)(filteredFormData)
        });
      }
    });
    checkChanges = elements.length !== length;
  };

  while (checkChanges) {
    _loop2();
  }

  return _objectSpread(_objectSpread({}, config), {}, {
    elements: elements
  });
}
export default function useDynamicElements(props) {
  var _props$fillProps;

  var _useStatePreferInitia = useStatePreferInitial(props.formData),
      _useStatePreferInitia2 = _slicedToArray(_useStatePreferInitia, 2),
      formData = _useStatePreferInitia2[0],
      setFormData = _useStatePreferInitia2[1];

  var _useStatePreferInitia3 = useStatePreferInitial((props === null || props === void 0 ? void 0 : (_props$fillProps = props.fillProps) === null || _props$fillProps === void 0 ? void 0 : _props$fillProps.disableResetFormdata) ? undefined : props.formData),
      _useStatePreferInitia4 = _slicedToArray(_useStatePreferInitia3, 1),
      initialFormData = _useStatePreferInitia4[0];

  return _objectSpread(_objectSpread({}, props), {}, {
    __useDynamicElements_original_props__: props,
    formData: formData,
    config: dynamicElements(props.config, formData),
    onChange: function onChange() {
      var _props$fillProps2, _props$onChange;

      for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
        args[_key] = arguments[_key];
      }

      var formData = args[0].formData;
      var resetFormData = ((_props$fillProps2 = props.fillProps) === null || _props$fillProps2 === void 0 ? void 0 : _props$fillProps2.disableRemoveHiddenFormData) ? formData : resetDisabledToDefaultValues(formData, initialFormData, props.config, false);
      (_props$onChange = props.onChange) === null || _props$onChange === void 0 ? void 0 : _props$onChange.call.apply(_props$onChange, [props].concat(args));
      setFormData(resetFormData);
    }
  });
}
//# sourceMappingURL=useDynamicElements.js.map