import { computed, onBeforeUnmount, ref, watch } from "vue";
import { useCommitBus } from "./commit-bus.js";
import { useFormState } from "./state.js";
export function useFieldValue(options) {
  const { getAt, setAt } = useFormState();
  const equals = options.equals ?? Object.is;
  const uncontrolled = ref(void 0);
  const committed = computed(() => {
    const path = options.binding();
    const raw = path == null ? uncontrolled.value : getAt(path);
    return options.fromState(raw);
  });
  const local = ref(committed.value);
  const touched = ref(false);
  const draft = computed({
    get: () => local.value,
    set: (next) => {
      local.value = next;
      touched.value = true;
    }
  });
  function commit() {
    if (!touched.value) return;
    touched.value = false;
    if (equals(local.value, committed.value)) return;
    const path = options.binding();
    const next = options.toState(local.value);
    if (path == null) uncontrolled.value = next;
    else setAt(path, next);
  }
  watch(committed, (next) => {
    if (!touched.value) local.value = next;
  });
  const unregister = useCommitBus().register(commit);
  onBeforeUnmount(() => {
    unregister();
    commit();
  });
  return { draft, dirty: computed(() => touched.value), commit };
}
