import { User } from "@clerk/remix/api.server";
import { getAuth } from "@clerk/remix/ssr.server";
import { LoaderFunction, defer, redirect } from "@remix-run/node";
import { Await, useLoaderData, useNavigate } from "@remix-run/react";
import { Suspense, useEffect } from "react";
import { Theme, useTheme } from "remix-themes";
import { Routes } from "~/routes";
import { clerkClient } from "~/services/clerk.server";

const getUserWithPublicMetadata = async (userId: string) => {
  const startTime = Date.now();
  const TIMEOUT = 10000;
  const DELAY = 250;

  while (Date.now() - startTime < TIMEOUT) {
    const user = await clerkClient.users.getUser(userId);
    if (!user) throw new Error("User not found! " + userId);

    const { personalProjectId, personalEnvId } = user?.publicMetadata || {};
    if (personalProjectId && personalEnvId) {
      return user;
    }

    await new Promise((resolve) => setTimeout(resolve, DELAY));
  }
  throw new Error("Timeout reached without finding project!");
};

type LoaderData = {
  user: any;
};
export const loader: LoaderFunction = async (args) => {
  const auth = await getAuth(args);
  const token = await auth.getToken();
  if (!token || !auth.userId) {
    return redirect(Routes.auth.login);
  }

  const user = getUserWithPublicMetadata(auth.userId);
  return defer({ user });
};

const redirectComponent = (user: User) => {
  const navigate = useNavigate();

  useEffect(() => {
    const { personalProjectId, personalEnvId, hasOnboarded } = user?.publicMetadata || {};

    if (personalProjectId && personalEnvId) {
      const redirectPath = hasOnboarded ? Routes.app.project.env.dashboard : Routes.app.project.env.onboarding;
      navigate(
        redirectPath({
          projectId: personalProjectId as string,
          envId: personalEnvId as string,
        }),
        {
          unstable_viewTransition: true,
        },
      );
    }
  }, [user]);

  return null;
};

export default function RootRoute() {
  const { user } = useLoaderData<LoaderData>();
  const [theme] = useTheme();
  const isDarkMode = theme === Theme.DARK;

  return (
    <Suspense
      fallback={
        <div className="flex h-screen flex-col items-center justify-center gap-8">
          <img src={isDarkMode ? "/DarkModeLogo.svg" : "/LightModeLogo.svg"} alt={"Montelo Logo"} className={"w-48"} />
        </div>
      }
    >
      <Await resolve={user}>{redirectComponent}</Await>
    </Suspense>
  );
}
