import { computed, ref, provide, watch, inject } from "vue";
import { useProxiedModel } from "../proxied-model/index.mjs";
import { propsFactory, getCurrentInstance, getObjectValueByPath, setObjectValueByPath } from "../../utils/dist/index.mjs";
import { createSymbol } from "../../utils/symbol.mjs";
const FormKey = createSymbol("form");
const makeFormProps = propsFactory({
  disabled: Boolean,
  fastFail: Boolean,
  lazyValidation: Boolean,
  readonly: Boolean,
  valid: {
    type: Boolean,
    default: null
  },
  modelValue: Object,
  defaultValue: Object
});
function provideForm(props) {
  var _a;
  const vm = getCurrentInstance("provideForm");
  const valid = useProxiedModel(props, "valid");
  const model = useProxiedModel(props, "modelValue");
  const defaultValue = (_a = props.defaultValue) != null ? _a : {};
  if (!model.value && defaultValue) {
    model.value = JSON.parse(JSON.stringify(defaultValue));
  }
  const isDisabled = computed(() => props.disabled);
  const isReadonly = computed(() => props.readonly);
  const isValidating = ref(false);
  const items = /* @__PURE__ */ new Map();
  const watchs = /* @__PURE__ */ new Map();
  const errorMessages = ref([]);
  async function submit(e) {
    e.preventDefault();
    const results = [];
    let _valid = true;
    errorMessages.value = [];
    valid.value = null;
    isValidating.value = true;
    for (const [id, item] of items) {
      if (!item.validate)
        continue;
      const itemErrorMessages = await item.validate();
      if (itemErrorMessages.length > 0) {
        _valid = false;
        results.push({
          id,
          errorMessages: itemErrorMessages
        });
      }
      if (!_valid && props.fastFail)
        break;
    }
    errorMessages.value = results;
    valid.value = _valid;
    isValidating.value = false;
    vm == null ? void 0 : vm.emit("submit", model.value, e);
  }
  async function reset(e) {
    e.preventDefault();
    items.forEach((item) => {
      var _a2;
      return (_a2 = item.reset) == null ? void 0 : _a2.call(item);
    });
    valid.value = null;
    vm == null ? void 0 : vm.emit("reset", e);
  }
  async function resetValidation() {
    items.forEach((item) => {
      var _a2;
      return (_a2 = item.resetValidation) == null ? void 0 : _a2.call(item);
    });
    errorMessages.value = [];
    valid.value = null;
    vm == null ? void 0 : vm.emit("resetValidation");
  }
  provide(FormKey, {
    isDisabled,
    isReadonly,
    isValidating,
    items,
    register: (id, item) => {
      items.set(id, item);
      watchs.set(id, [
        watch(item.name, (name) => {
          if (!name)
            return;
          const val = getObjectValueByPath(model.value, name);
          if (val !== item.modelValue.value)
            item.modelValue.value = val;
        }, { immediate: true }),
        watch(item.modelValue, (value) => {
          const name = item.name.value;
          if (!name)
            return;
          if (value !== getObjectValueByPath(model.value, name)) {
            setObjectValueByPath(model.value, name, value);
          }
        }, { immediate: true, deep: true })
      ]);
    },
    unregister: (id) => {
      var _a2;
      items.delete(id);
      (_a2 = watchs.get(id)) == null ? void 0 : _a2.forEach((v) => v());
      watchs.delete(id);
    }
  });
  return {
    errorMessages,
    isDisabled,
    isReadonly,
    isValidating,
    items,
    submit,
    reset,
    resetValidation
  };
}
function useForm() {
  return inject(FormKey, null);
}
export {
  FormKey,
  makeFormProps,
  provideForm,
  useForm
};
//# sourceMappingURL=index.mjs.map
