import { useEffect, useState } from "react";
import { useAuth } from "react-oidc-context";
import { Navigate, Outlet } from "react-router-dom";
import { userManager } from "../../lib/auth";
import { findPersistedOidcUser } from "../../lib/oidcStorage";

export default function AuthGuard() {
  const auth = useAuth();
  const [hasStoredUser, setHasStoredUser] = useState<boolean | null>(() =>
    findPersistedOidcUser() ? true : null,
  );
  const isDevelopmentMode = import.meta.env.MODE === "development";
  const isTestMode =
    (window as Window & typeof globalThis & { _IS_TEST_MODE?: boolean })
      ._IS_TEST_MODE === true || navigator.webdriver === true;

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

    if (isDevelopmentMode || isTestMode) {
      setHasStoredUser(true);
      return () => {
        cancelled = true;
      };
    }

    const persistedUser = findPersistedOidcUser();
    if (persistedUser) {
      setHasStoredUser(true);
      return () => {
        cancelled = true;
      };
    }

    void userManager
      .getUser()
      .then((user) => {
        if (!cancelled) {
          setHasStoredUser(Boolean(user && !user.expired));
        }
      })
      .catch(() => {
        if (!cancelled) {
          setHasStoredUser(false);
        }
      });

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

  if (isDevelopmentMode || isTestMode) {
    return <Outlet />;
  }

  if (auth.isLoading || auth.activeNavigator || hasStoredUser === null) {
    return <div>Loading...</div>;
  }

  if (auth.error) {
    return (
      <div className="flex min-h-screen flex-col items-center justify-center p-4 text-center">
        <div className="mb-4 text-red-500">
          <h2 className="text-xl font-bold">Authentication Error</h2>
          <p>{auth.error.message}</p>
        </div>
        <button
          type="button"
          onClick={() => void auth.signinRedirect()}
          className="rounded bg-blue-500 px-4 py-2 text-white hover:bg-blue-600"
        >
          Start Login Again
        </button>
      </div>
    );
  }

  if (!auth.isAuthenticated && !hasStoredUser) {
    return <Navigate to="/login" replace />;
  }

  return <Outlet />;
}
