import { useForm } from "react-hook-form";
import { useDataContext } from "../../common/contexts/data_context";
import { useAuth } from "../contexts/auth_context";
import { router } from "expo-router";
import { ApiRequestStatus } from "../../common/const/api_request_states";
import { useCallback, useState } from "react";
import { ApiResponseError } from "../errors/api_response_error";

export interface SignUpFormValues {
  name: string;
  lastName: string;
  email: string;
  password: string;
  confirmPassword: string;
  dateOfBirth: string;
}

export const useSignUp = () => {
  const { control, setError, handleSubmit } = useForm<SignUpFormValues>();
  const { authRepository } = useDataContext();
  const { login } = useAuth();
  const [requestStatus, setRequestStatus] = useState(ApiRequestStatus.IDLE);
  const [isErrorModalVisible, setIsErrorModalVisible] = useState(false);

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

  const validSubmit = async (data: SignUpFormValues) => {
    try {
      if (data.password !== data.confirmPassword) {
        setError("confirmPassword", {
          type: "manual",
          message: "Passwords don't match",
        });
        return;
      }
      await setLoading();
      const userToRegister = {
        name: data.name,
        lastName: data.lastName,
        email: data.email,
        password: data.password,
        confirmPassword: data.confirmPassword,
        birthdate: data.dateOfBirth,
      };
      const { user, token } = await authRepository!.register(userToRegister);
      await login(user, token);
      setRequestStatus(ApiRequestStatus.SUCCESS);
      router.replace("/(tabs)");
    } catch (error: any) {
      const { status } = error as ApiResponseError;
      switch (status) {
        case 400:
          setError("email", {
            type: "manual",
            message: "Email already in use",
          });
          setRequestStatus(ApiRequestStatus.ERROR);
          break;
        default:
          setIsErrorModalVisible(true);
          setRequestStatus(ApiRequestStatus.ERROR);
          break;
      }
    }
  };

  const closeErrorModal = () => {
    setIsErrorModalVisible(false);
  };

  const invalidSubmit = (errors: any) => {
    console.log(errors);
  };

  const onSubmit = useCallback(async () => {
    await handleSubmit(validSubmit, invalidSubmit)();
  }, [handleSubmit, validSubmit, invalidSubmit]);

  return {
    control,
    onSubmit,
    requestStatus,
    isErrorModalVisible,
    closeErrorModal,
  };
};
