import { useForm } from "react-hook-form";
import { useDataContext } from "../../common/contexts/data_context";
import { useState } from "react";
import { ApiRequestStatus } from "../../common/const/api_request_states";
import { router } from "expo-router";
import {
  ChangePaswordError,
  ResetPasswordError,
} from "../errors/reset_password_error";

export interface ResetPasswordFormValues {
  email: string;
  newPassword: string;
  newPasswordConfirmation: string;
  code: string;
}

export const useResetPassword = () => {
  const { authRepository } = useDataContext();
  const { control, handleSubmit, getValues, setError, setValue } =
    useForm<ResetPasswordFormValues>({
      defaultValues: {
        email: "",
        newPassword: "",
        newPasswordConfirmation: "",
        code: "",
      },
    });
  const [status, setStatus] = useState(ApiRequestStatus.IDLE);

  const setLoading = async () => {
    setStatus(ApiRequestStatus.LOADING);
  };

  const getResetCode = async () => {
    await setLoading();
    if (!getValues().email) {
      setError("email", { type: "manual", message: "Email is required" });
      throw new Error("Email is required");
    }
    await authRepository!.getResetCode(getValues().email);
    setStatus(ApiRequestStatus.SUCCESS);
  };

  const validSubmit = async (data: ResetPasswordFormValues) => {
    try {
      await setLoading();
      if (data.newPassword !== data.newPasswordConfirmation) {
        setError("newPasswordConfirmation", {
          type: "manual",
          message: "Passwords do not match",
        });
        return;
      }
      await authRepository!.resetPassword({
        newPassword: data.newPassword,
        code: data.code,
        email: data.email,
      });
      router.replace("/login");
    } catch (error) {
      if (
        error instanceof ResetPasswordError &&
        error.type == ChangePaswordError.UNDEFINED
      ) {
        throw new Error();
      }
    }
  };

  const errorSubmit = async () => {
    throw new Error();
  };

  const onSubmit = async () => {
    await handleSubmit(validSubmit, errorSubmit)();
  };

  return {
    control,
    getResetCode,
    setValue,
    onSubmit,
    status,
  };
};
