import React, {
  createContext,
  useCallback,
  useContext,
  useEffect,
  useMemo,
  useState,
} from "react";
import {
  consumeTokenFromUrl,
  getStoredAuth,
  clearStoredAuth,
  redirectToHseLogin,
  isAdminRole,
  roleFromJwt,
  userFromJwt,
} from "hse-auth";

const AuthContext = createContext(null);

export function AuthProvider({ children }) {
  const [auth, setAuth] = useState(() => getStoredAuth());
  const [booting, setBooting] = useState(true);

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

    (async () => {
      const fromUrl = await consumeTokenFromUrl();
      if (cancelled) return;

      if (fromUrl) {
        setAuth(fromUrl);
        setBooting(false);
        return;
      }
      if (!getStoredAuth()?.token) {
        setBooting(false);
        redirectToHseLogin();
        return;
      }
      setAuth(getStoredAuth());
      setBooting(false);
    })();

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

  const logout = useCallback(() => {
    clearStoredAuth();
    setAuth(null);
    redirectToHseLogin();
  }, []);

  const value = useMemo(
    () => ({
      auth,
      isAuthenticated: Boolean(auth?.token),
      isAdmin: isAdminRole(auth?.role || roleFromJwt(auth?.token || "")),
      booting,
      logout,
    }),
    [auth, booting, logout]
  );

  return (
    <AuthContext.Provider value={value}>{children}</AuthContext.Provider>
  );
}

export function useAuth() {
  const ctx = useContext(AuthContext);
  if (!ctx) {
    throw new Error("useAuth must be used within AuthProvider");
  }
  return ctx;
}

export { userFromJwt, roleFromJwt };
