"use strict";
const toHaveFormValues$1 = require("../../../../_virtual/to-have-form-values.cjs");
const interopRequireDefault = require("../../../@babel/runtime/helpers/interopRequireDefault.cjs");
const _extends = require("../../../@babel/runtime/helpers/extends.cjs");
const isEqualWith = require("../../../lodash/isEqualWith.cjs");
const uniq = require("../../../lodash/uniq.cjs");
const css_escape = require("../../../css.escape/css.escape.cjs");
require("./utils.cjs");
const utils = require("../../../../_virtual/utils.cjs");
var _interopRequireDefault = interopRequireDefault.interopRequireDefaultExports;
Object.defineProperty(toHaveFormValues$1.__exports, "__esModule", {
  value: true
});
toHaveFormValues$1.__exports.toHaveFormValues = toHaveFormValues;
var _extends2 = _interopRequireDefault(_extends.__require());
var _isEqualWith = _interopRequireDefault(isEqualWith.__require());
var _uniq = _interopRequireDefault(uniq.__require());
var _css = _interopRequireDefault(css_escape.__require());
var _utils = utils.__exports;
function getMultiElementValue(elements) {
  const types = (0, _uniq.default)(elements.map((element) => element.type));
  if (types.length !== 1) {
    throw new Error("Multiple form elements with the same name must be of the same type");
  }
  switch (types[0]) {
    case "radio": {
      const theChosenOne = elements.find((radio) => radio.checked);
      return theChosenOne ? theChosenOne.value : void 0;
    }
    case "checkbox":
      return elements.filter((checkbox) => checkbox.checked).map((checkbox) => checkbox.value);
    default:
      return elements.map((element) => element.value);
  }
}
function getFormValue(container, name) {
  const elements = [...container.querySelectorAll(`[name="${(0, _css.default)(name)}"]`)];
  if (elements.length === 0) {
    return void 0;
  }
  switch (elements.length) {
    case 1:
      return (0, _utils.getSingleElementValue)(elements[0]);
    default:
      return getMultiElementValue(elements);
  }
}
function getPureName(name) {
  return /\[\]$/.test(name) ? name.slice(0, -2) : name;
}
function getAllFormValues(container) {
  const names = Array.from(container.elements).map((element) => element.name);
  return names.reduce((obj, name) => (0, _extends2.default)({}, obj, {
    [getPureName(name)]: getFormValue(container, name)
  }), {});
}
function toHaveFormValues(formElement, expectedValues) {
  (0, _utils.checkHtmlElement)(formElement, toHaveFormValues, this);
  if (!formElement.elements) {
    throw new Error("toHaveFormValues must be called on a form or a fieldset");
  }
  const formValues = getAllFormValues(formElement);
  return {
    pass: Object.entries(expectedValues).every(([name, expectedValue]) => (0, _isEqualWith.default)(formValues[name], expectedValue, _utils.compareArraysAsSet)),
    message: () => {
      const to = this.isNot ? "not to" : "to";
      const matcher = `${this.isNot ? ".not" : ""}.toHaveFormValues`;
      const commonKeyValues = Object.keys(formValues).filter((key) => expectedValues.hasOwnProperty(key)).reduce((obj, key) => (0, _extends2.default)({}, obj, {
        [key]: formValues[key]
      }), {});
      return [this.utils.matcherHint(matcher, "element", ""), `Expected the element ${to} have form values`, this.utils.diff(expectedValues, commonKeyValues)].join("\n\n");
    }
  };
}
module.exports = toHaveFormValues$1.__exports;
//# sourceMappingURL=to-have-form-values.cjs.map
