import { useEffect, useState } from "react";
import { Center, Spinner } from "@chakra-ui/react";
import { Navigate } from "react-router-dom";

type AuthGuardProps = {
  children: React.ReactNode;
  fetchCurrentUser: () => Promise<unknown>;
  redirectTo?: string;
  loadingFallback?: React.ReactNode;
  authenticatedWrapper?: (children: React.ReactNode) => React.ReactNode;
};

export function AuthGuard({
  children,
  fetchCurrentUser,
  redirectTo = "/login",
  loadingFallback,
  authenticatedWrapper
}: AuthGuardProps) {
  const [state, setState] = useState<{ loading: boolean; authenticated: boolean }>({
    loading: true,
    authenticated: false
  });

  useEffect(() => {
    let cancelled = false;

    fetchCurrentUser()
      .then(() => {
        if (!cancelled) {
          setState({ loading: false, authenticated: true });
        }
      })
      .catch(() => {
        if (!cancelled) {
          setState({ loading: false, authenticated: false });
        }
      });

    return () => {
      cancelled = true;
    };
  }, [fetchCurrentUser]);

  if (state.loading) {
    return (
      <>
        {loadingFallback ?? (
          <Center h="var(--app-height)">
            <Spinner size="xl" />
          </Center>
        )}
      </>
    );
  }

  if (!state.authenticated) {
    return <Navigate to={redirectTo} replace />;
  }

  return <>{authenticatedWrapper ? authenticatedWrapper(children) : children}</>;
}
