import { createContext, useState, useCallback, useEffect, useMemo, createElement } from "react";
import { useSessionToken } from "@contember/react-client";
import { Message, ContainerSpinner } from "@contember/ui";
import { MiscPageLayout } from "../MiscPageLayout.js";
import { InvalidIdentityFallback } from "./InvalidIdentityFallback.js";
import { useLogout } from "./useLogout.js";
import { useFetchMe } from "../../tenant/queries/me.js";
const IdentityContext = createContext(void 0);
const IdentityRefreshContext = createContext(() => {
  throw new Error("IdentityRefreshContext is not initialized");
});
const IdentityProvider = ({ children, onInvalidIdentity, allowUnauthenticated }) => {
  const sessionToken = useSessionToken();
  const fetchMe = useFetchMe();
  const [identityState, setIdentityState] = useState(() => ({ state: sessionToken ? "loading" : "none" }));
  const logout = useLogout();
  const clearIdentity = useCallback(() => setIdentityState({ state: "cleared" }), []);
  const refetch = useCallback(async () => {
    setIdentityState({ state: "loading" });
    try {
      const response = await fetchMe();
      const person = response.data.me.person;
      const projects = response.data.me.projects;
      const permissions = response.data.me.permissions;
      setIdentityState({
        state: "success",
        identity: {
          email: person.email,
          otpEnabled: person.otpEnabled,
          personId: person.id,
          projects: projects.map((it) => ({
            name: it.project.name,
            slug: it.project.slug,
            roles: it.memberships.map((it2) => it2.role)
          })),
          permissions
        }
      });
    } catch (e) {
      console.error(e);
      if ("status" in e && e.status === 401) {
        logout({ noRedirect: true });
        clearIdentity();
        if (onInvalidIdentity) {
          onInvalidIdentity();
        } else if (window.location.pathname !== "/") {
          window.location.href = "/";
        }
      } else {
        setIdentityState({ state: "failed" });
      }
    }
  }, [clearIdentity, fetchMe, logout, onInvalidIdentity]);
  useEffect(() => {
    if (sessionToken === void 0) {
      setIdentityState({ state: "none" });
      if (!allowUnauthenticated) {
        if (onInvalidIdentity) {
          onInvalidIdentity();
        } else if (window.location.pathname !== "/") {
          window.location.href = "/";
        }
      }
      return;
    }
  }, [sessionToken, allowUnauthenticated, onInvalidIdentity]);
  useEffect(() => {
    if (sessionToken !== void 0) {
      refetch();
    }
  }, [sessionToken, refetch]);
  const identityContextValue = useMemo(() => identityState.state === "success" ? { clearIdentity, identity: identityState.identity } : void 0, [identityState, clearIdentity]);
  if (identityState.state === "cleared") {
    return /* @__PURE__ */ createElement(MiscPageLayout, null, /* @__PURE__ */ createElement(Message, {
      size: "large",
      flow: "generousBlock"
    }, "Logging out\u2026"));
  }
  if (identityState.state === "failed") {
    return /* @__PURE__ */ createElement(InvalidIdentityFallback, null);
  }
  if (identityState.state === "loading" || !allowUnauthenticated && identityState.state === "none") {
    return /* @__PURE__ */ createElement(ContainerSpinner, null);
  }
  return /* @__PURE__ */ createElement(IdentityContext.Provider, {
    value: identityContextValue
  }, /* @__PURE__ */ createElement(IdentityRefreshContext.Provider, {
    value: refetch
  }, children));
};
export { IdentityContext, IdentityProvider, IdentityRefreshContext };
//# sourceMappingURL=IdentityProvider.js.map
