"use strict";

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

var _core = require("@formily/core");

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) { _defineProperty(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; }

function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }

var OP_MAPS = {
  '*': function _() {
    return true;
  },
  '=': function _(l, r) {
    return l === r;
  },
  '==': function _(l, r) {
    return l === r;
  },
  '!': function _(l, r) {
    return l !== r;
  },
  '!=': function _(l, r) {
    return l != r;
  },
  '>': function _(l, r) {
    return l > r;
  },
  '<': function _(l, r) {
    return l < r;
  },
  '>=': function _(l, r) {
    return l >= r;
  },
  '<=': function _(l, r) {
    return l <= r;
  },
  ied: function ied(l, r) {
    if (Array.isArray(l) || typeof l === 'string' && r) {
      return l.includes(r);
    } else {
      return false;
    }
  },
  eed: function eed(l, r) {
    if (Array.isArray(l) || typeof l === 'string' && r) {
      return !l.includes(r);
    } else {
      return true;
    }
  },
  i: function i(l, r) {
    if (Array.isArray(r) || typeof r === 'string' && l) {
      return r.includes(l);
    } else {
      return false;
    }
  },
  e: function e(l, r) {
    if (Array.isArray(r) || typeof r === 'string' && l) {
      return !r.includes(l);
    } else {
      return true;
    }
  },
  isEmpty: function isEmpty(l, r) {
    return l === null || l === undefined || l === '' || Array.isArray(l) && l.length === 0;
  },
  notEmpty: function notEmpty(l, r) {
    return l !== null && l !== undefined && l !== '' && (!Array.isArray(l) || l.length !== 0);
  }
};

var getParsedValue = function getParsedValue(value, scope) {
  if (typeof value === 'string' && value.startsWith('${') && value.endsWith('}')) {
    return scope.$form.getValuesIn(value.slice(2, value.length - 1));
  } else if (typeof value === 'string' && value.startsWith('{{') && value.endsWith('}}')) {
    var code = value.slice(2, value.length - 2);

    try {
      return new Function("with(this){ return ".concat(code, " }")).call(scope);
    } catch (e) {
      return undefined;
    }
  } else {
    return value;
  }
};

var bingo = function bingo(bingoItem, scope) {
  var _bingoItem$when = bingoItem.when,
      when = _bingoItem$when === void 0 ? [] : _bingoItem$when,
      _bingoItem$logic = bingoItem.logic,
      logic = _bingoItem$logic === void 0 ? '&&' : _bingoItem$logic;
  var result = logic === '&&';
  when.forEach(function (_ref) {
    var left = _ref.left,
        op = _ref.op,
        right = _ref.right;
    var leftValue = scope.$form.getValuesIn(left);
    var rightValue = getParsedValue(right, scope);
    var itemResult = OP_MAPS[op](leftValue, rightValue);

    if (logic === '&&') {
      result = result && itemResult;
    } else {
      result = result || itemResult;
    }
  });
  return result;
};

var loopAddFieldEffect = function loopAddFieldEffect(schema, form, scope) {
  if (Array.isArray(schema)) {
    schema === null || schema === void 0 ? void 0 : schema.forEach(function (item) {
      if (item.name) {
        var _item$cascade, _item$onChange;

        (_item$cascade = item.cascade) === null || _item$cascade === void 0 ? void 0 : _item$cascade.forEach(function (cascade) {
          (0, _core.onFieldReact)(item.name, function (field) {
            var contextScope = _objectSpread(_objectSpread({}, scope), {}, {
              $form: form,
              $self: field,
              $values: form.values
            });

            var _cascade$state = cascade.state,
                state = _cascade$state === void 0 ? {} : _cascade$state,
                _cascade$props = cascade.props,
                props = _cascade$props === void 0 ? {} : _cascade$props,
                dataSourceFilter = cascade.dataSourceFilter,
                dataSourceHide = cascade.dataSourceHide;

            if (bingo(cascade, contextScope)) {
              if (dataSourceFilter || dataSourceHide) {
                var sourceDataSource = field.getState()._sourceDataSource;

                if (!sourceDataSource) {
                  var dataSource = field.getState().dataSource;
                  field.setState({
                    _sourceDataSource: dataSource
                  });
                  sourceDataSource = dataSource;
                }

                if (sourceDataSource) {
                  var nextDataSource = sourceDataSource.filter(function (item) {
                    if (Array.isArray(dataSourceFilter)) {
                      return dataSourceFilter.includes(item.value);
                    }

                    if (Array.isArray(dataSourceHide)) {
                      return !dataSourceFilter.includes(item.value);
                    }
                  });
                  field.setDataSource(nextDataSource);
                  var value = field.getState().value;

                  if (!nextDataSource.some(function (item) {
                    return item.value === value;
                  })) {
                    field.setValue(undefined);
                  }
                }
              }

              var nextState = {};
              Object.keys(state).forEach(function (stateKey) {
                nextState[stateKey] = getParsedValue(state[stateKey], contextScope);
              });
              field.setState(nextState);
              var nextProps = {};
              Object.keys(props).forEach(function (propsKey) {
                nextProps[propsKey] = getParsedValue(props[propsKey], contextScope);
              });
              field.setComponentProps(nextProps);
            } else {
              var formState = form.getState();

              if (dataSourceFilter || dataSourceHide) {
                var _sourceDataSource = field.getState()._sourceDataSource;

                _sourceDataSource && field.setDataSource(_sourceDataSource);
              }

              var _nextState = {};
              Object.keys(state).forEach(function (stateKey) {
                _nextState[stateKey] = stateKey in item ? item[stateKey] : formState[stateKey];
              });
              field.setState(_nextState);
              var _nextProps = {};
              Object.keys(props).forEach(function (propsKey) {
                _nextProps[propsKey] = item.props ? item.props[propsKey] : undefined;
              });
              field.setComponentProps(_nextProps);
            }
          });
        });
        (_item$onChange = item.onChange) === null || _item$onChange === void 0 ? void 0 : _item$onChange.forEach(function (onChange) {
          (0, _core.onFieldValueChange)(item.name, function (field) {
            var contextScope = _objectSpread(_objectSpread({}, scope), {}, {
              $form: form,
              $self: field,
              $values: form.values
            });

            var values = onChange.values;

            if (bingo(onChange, contextScope)) {
              Object.keys(values).forEach(function (valuesKey) {
                form.setValuesIn(valuesKey, getParsedValue(values[valuesKey], contextScope));
              });
            }
          });
        });
      } else if (item.children) {
        loopAddFieldEffect(item.children, form, scope);
      }
    });
  }
};

var _default = function _default(form, schema, scope) {
  form.addEffects('cascade', function () {
    loopAddFieldEffect(schema, form, scope);
  });
};

exports.default = _default;