import { useCallback, useMemo } from "react";
import { useDispatch, useSelector } from "react-redux";
import { actions, selectors } from "../store";
import { AuthToken, User } from "../api";
import { AuthContext } from "./AuthContext";
import { IUser } from "@/api/resources/User";

export function AuthProvider({
  children,
}: React.PropsWithChildren<unknown>): JSX.Element {
  const dispatch = useDispatch();
  const token = useSelector(selectors.selectToken);
  const user = useSelector(selectors.selectUser);
  const { gender, partnerGender, birthdate, partnerBirthdate, birthPlace, partnerBirthPlace } = useSelector(selectors.selectQuestionnaire);

  const signUp = useCallback(
    (token: AuthToken, user: User.User, newUser?: IUser, isAnonymous?: boolean): AuthToken => {
      dispatch(actions.token.update(token));
      dispatch(actions.user.update(user));
      dispatch(actions.form.addEmail(user.email));
      if (user.profile.birthday?.length) {
        dispatch(actions.form.addDate(user.profile.birthday.split(" ")[0]));
        dispatch(
          actions.form.addTime(
            new Date(user.profile.birthday).toLocaleTimeString()
          )
        );
      }
      if (newUser && !isAnonymous) {
        dispatch(actions.questionnaire.update({
          gender: newUser.profile?.gender || gender || undefined,
          birthPlace: newUser.profile?.birthplace?.address || birthPlace || undefined,
          birthdate: newUser.profile?.birthdate || birthdate || undefined,
          partnerBirthPlace: newUser.partner?.birthplace?.address || partnerBirthPlace || undefined,
          partnerBirthdate: newUser.partner?.birthdate || partnerBirthdate || undefined,
          partnerGender: newUser.partner?.gender || partnerGender || undefined,
        }))

        dispatch(actions.user.update({
          username: newUser.profile?.name ?? undefined,
        }));
      }
      return token;
    },
    [dispatch, gender, partnerGender, birthdate, partnerBirthdate, birthPlace, partnerBirthPlace]
  );
  const logout = useCallback(() => dispatch(actions.reset()), [dispatch]);
  const auth = useMemo(
    () => ({
      signUp,
      logout,
      token,
      user: user.id ? user : null,
    }),
    [token, user, signUp, logout]
  );
  return <AuthContext.Provider value={auth}>{children}</AuthContext.Provider>;
}
