import * as Yup from "yup";
import { useFormik } from "formik";
import { UserStore } from "../domain/userStore";
import React from "react";
import { updateEmailUseCase } from "../useCases/updateEmailUseCase";
import Failure from "core/failure";
import { useTranslation } from "react-i18next";

type FormValues = {
  email: string;
};

type FormValuesValidation = {
  [Prop in keyof FormValues]: any;
};

function useEmailDataViewModel(store: UserStore) {
  const { t } = useTranslation();

  const updateEmail = React.useCallback(
    (payload: string) =>
      updateEmailUseCase(
        {
          user: store.user,
          setUser: store.setUser,
          updateUser: store.updateUser,
        },
        payload
      ),
    [store.user, store.setUser, store.updateUser]
  );

  const formik = useFormik<FormValues>({
    initialValues: {
      email: store.user?.email || "",
    },
    validationSchema: Yup.object().shape<FormValuesValidation>({
      email: Yup.string()
        .email("invalid email address")
        .required("required field"),
    }),
    enableReinitialize: true,
    onSubmit: (
      payload,
      { setSubmitting, resetForm, setStatus }
    ): Promise<void> | undefined => {
      setSubmitting(true);
      return updateEmail(payload.email)
        ?.then(() => {
          setSubmitting(false);
          setStatus({ fullfilled: true });
        })
        .catch((reason: Failure) => {
          formik.setErrors({ email: reason.mapKeyWith(t) });
          setStatus({ fullfilled: false });
          setSubmitting(false);
          resetForm();
        });
    },
  });
  return {
    status: formik.status,
    isValid: formik.isValid,
    isSubmiting: store.isUpdating,
    email: formik.values.email,
    errors: formik.errors,
    touched: formik.touched,
    onEmailChange: formik.handleChange,
    onSubmit: formik.handleSubmit,
    onBlur: formik.handleBlur,
    reset: formik.resetForm,
  };
}

export { useEmailDataViewModel };
export type { FormValues };
