import { nextTick, ref } from "vue";
import { useScroll } from "src/composables/useScroll";

export const useSubmitHandler = (options = {}) => {
  const { containerRef, formRef, onError, onSuccess, scrollFn } = options;

  const { scrollToFirstError } = useScroll();

  const loading = ref(false);

  const validationErrors = ref({});

  const execute = async (apiCallThunk) => {
    loading.value = true;

    validationErrors.value = {};

    let allValid = true;

    const refsToValidate = getFormRefs();

    if (refsToValidate.length > 0) {
      for (const ref of refsToValidate) {
        if (ref) {
          const success = await ref.validate(true);

          if (!success) {
            allValid = false;
          }
        }
      }
    }

    if (!allValid) {
      loading.value = false;

      await showFirstError();

      throw new Error("Frontend validation failed.");
    }

    try {
      const response = await apiCallThunk();

      if (typeof onSuccess === "function") {
        await onSuccess(response);
      } else {
        return response;
      }
    } catch (error) {
      await handleError(error);
    } finally {
      loading.value = false;
    }
  };

  const getFormRefs = () => {
    const refs = formRef?.value;

    if (!refs) return [];

    return Array.isArray(refs) ? refs : [refs];
  };

  const handleError = async (error) => {
    if (error?.response?.status === 422) {
      const errors = error.response.data.errors || {};

      for (const key in errors) {
        const message = errors[key][0];

        validationErrors.value[key] = message;
      }

      await showFirstError();
    }

    await nextTick();

    if (typeof onError === "function") {
      await onError(error);
    } else {
      throw error;
    }
  };

  const showFirstError = () => scrollToFirstError(formRef, containerRef, { scrollFn });

  return {
    loading,
    validationErrors,
    execute,
  };
}
