/* eslint-disable @typescript-eslint/no-explicit-any */
import React, { forwardRef, useCallback } from "react";
import { useWillMount } from "@reins/hooks";

import { FormProps } from "./form.types";
import { useActions } from "hooks/use-actions/use-actions";
import { FormAdapter } from "utils";

export const Form = forwardRef<
  HTMLFormElement,
  FormProps<any> & {
    formAdapter: FormAdapter<any, string>;
    Provider: React.FC<{ form: FormAdapter<any, string>; children: React.ReactNode }>;
  }
>(({ initialPage, formAdapter, children, onSubmit, Provider, ...rest }, ref) => {
  useWillMount(() => {
    formAdapter.store.setState((draft: any) => {
      if (typeof initialPage === "number") {
        draft.page = initialPage;
      }
    });
  });

  const [{ isLastPage, isMultiPage }] = formAdapter.store.useStore({
    selector: (state: any) =>
      ({
        isMultiPage: state.pages > 1,
        isFirstPage: state.page === 1,
        isLastPage: state.page === state.pages,
      }) as const,
  });

  const { goToPage } = useActions(formAdapter);

  const handleFormReset = useCallback(
    (event: React.FormEvent<HTMLFormElement>) => {
      event.preventDefault();
      formAdapter.reset();
    },
    [formAdapter],
  );

  const onSubmitCallback = useCallback(
    (values: any) => {
      if (isLastPage) return onSubmit(values);
      goToPage((prevState) => prevState + 1);
    },
    [isLastPage, isMultiPage],
  );

  const handleFormSubmit = useCallback(
    (event: React.FormEvent<HTMLFormElement>) => {
      event.preventDefault();
      formAdapter.submit(onSubmitCallback);
    },
    [formAdapter, onSubmitCallback],
  );

  return (
    <Provider form={formAdapter}>
      <form {...rest} onSubmit={handleFormSubmit} onReset={handleFormReset} ref={ref}>
        {children}
      </form>
    </Provider>
  );
});
