import { useCurrentUser, useLoginMutation } from "@/api/auth";
import { deleteAuthToken, getAuthToken } from "@/utils/token-storage";
import { useQueryClient } from "@tanstack/react-query";
import { router } from "expo-router";
import { ReactNode, useEffect, useState } from "react";
import AuthContext, { LoginOptions } from "./context";

interface AuthProviderProps {
  children: ReactNode;
}


function AuthProvider({ children }: AuthProviderProps) {
  const [storageStatus, setStorageStatus] = useState<"pending"|"hasKey"|"noKey">("pending");
  const { data: user, isLoading: isLoadingUser, refetch: refetchUser } = useCurrentUser();
  const {
    mutate: mutateLogin,
    isPending: isPendingLogin,
    error: errorLogin,
  } = useLoginMutation();
  const queryClient = useQueryClient();

  useEffect(() => {
    const authTokenFunc = async () => {
      const token = await getAuthToken()
      if(token)
        setStorageStatus("hasKey");
      else
        setStorageStatus("noKey");
    }
    authTokenFunc();
  }, []);

  const isAuthorized = !!user;
  const isLoading = (isLoadingUser || isPendingLogin) && storageStatus === "hasKey";

  const login = (email: string, password: string, options?: LoginOptions) => {
    mutateLogin({
      email,
      password,
    }, {
      onSuccess: (data) => {
        refetchUser();
        setStorageStatus("hasKey");
        router.push("/(tabs)/me");

        if(!options)
          return;

        if(options.onSuccess)
          options.onSuccess(data);
      },
      onError: (error) => {
        if(!options)
          return;

        if(options.onError)
          options.onError(error);
      }
    });
  };
  const logout = async () => {
    await deleteAuthToken();
    setStorageStatus("noKey");
    queryClient.invalidateQueries({
      queryKey: ["current-user"]
    });
    queryClient.setQueryData(["current-user"], null);
  };

  return (
    <AuthContext.Provider
      value={{ user, isLoading, isAuthorized, login, logout, errorLogin, isPendingLogin }}
    >
      {children}
    </AuthContext.Provider>
  );
}

export default AuthProvider;
