import { objectWithoutProperties as _objectWithoutProperties, objectSpread2 as _objectSpread2 } from './_virtual/_rollupPluginBabelHelpers.mjs';
import { useState, useEffect, useLayoutEffect, useId } from 'react';
import { flushSync } from 'react-dom';
import { createFormContext, useSubjectRef, useFormState, getFormMetadata, useFormContext, getFieldMetadata } from './context.mjs';

var _excluded = ["id"];

/**
 * useLayoutEffect is client-only.
 * This basically makes it a no-op on server
 */
var useSafeLayoutEffect = typeof document === 'undefined' ? useEffect : useLayoutEffect;
function useFormId(preferredId) {
  var id = useId();
  return preferredId !== null && preferredId !== void 0 ? preferredId : id;
}
function useNoValidate() {
  var defaultNoValidate = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
  var [noValidate, setNoValidate] = useState(defaultNoValidate);
  useSafeLayoutEffect(() => {
    // This is necessary to fix an issue in strict mode with related to our proxy setup
    // It avoids the component from being rerendered without re-rendering the child
    // Which reset the proxy but failed to capture its usage within child component
    if (!noValidate) {
      setNoValidate(true);
    }
  }, [noValidate]);
  return noValidate;
}
function useForm(options) {
  var {
      id
    } = options,
    formConfig = _objectWithoutProperties(options, _excluded);
  var formId = useFormId(id);
  var [context] = useState(() => createFormContext(_objectSpread2(_objectSpread2({}, formConfig), {}, {
    onSchedule: callback => flushSync(callback),
    formId
  })));
  useSafeLayoutEffect(() => {
    document.addEventListener('input', context.onInput);
    document.addEventListener('focusout', context.onBlur);
    document.addEventListener('reset', context.onReset);
    return () => {
      document.removeEventListener('input', context.onInput);
      document.removeEventListener('focusout', context.onBlur);
      document.removeEventListener('reset', context.onReset);
    };
  }, [context]);
  useSafeLayoutEffect(() => {
    context.onUpdate(_objectSpread2(_objectSpread2({}, formConfig), {}, {
      formId
    }));
  });
  var subjectRef = useSubjectRef();
  var state = useFormState(context, subjectRef);
  var noValidate = useNoValidate(options.defaultNoValidate);
  var form = getFormMetadata(formId, state, subjectRef, context, noValidate);
  return [form, form.getFieldset()];
}
function useFormMetadata(formId) {
  var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  var subjectRef = useSubjectRef();
  var context = useFormContext(formId);
  var state = useFormState(context, subjectRef);
  var noValidate = useNoValidate(options.defaultNoValidate);
  return getFormMetadata(context.formId, state, subjectRef, context, noValidate);
}
function useField(name) {
  var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  var subjectRef = useSubjectRef();
  var context = useFormContext(options.formId);
  var state = useFormState(context, subjectRef);
  var field = getFieldMetadata(context.formId, state, subjectRef, name);
  var form = getFormMetadata(context.formId, state, subjectRef, context, false);
  return [field, form];
}

export { useField, useForm, useFormId, useFormMetadata, useNoValidate, useSafeLayoutEffect };
