import { getI18n } from "react-i18next";
import RealmRepresentation from "@keycloak/keycloak-admin-client/lib/defs/realmRepresentation";
import {
  createNamedContext,
  useEnvironment,
  useFetch,
  useRequiredContext,
} from "@keycloakify/keycloak-admin-ui/ui-shared";
import { PropsWithChildren, useEffect, useState } from "react";
import { useMatch } from "react-router-dom";
import { useAdminClient } from "@keycloakify/keycloak-admin-ui/admin-client";
import { DashboardRouteWithRealm } from "@keycloakify/keycloak-admin-ui/dashboard/routes/Dashboard";

type RealmContextType = {
  realm: string;
  realmRepresentation?: RealmRepresentation;
  refresh: () => void;
};

export const RealmContext = createNamedContext<RealmContextType | undefined>(
  "RealmContext",
  undefined,
);

export const RealmContextProvider = ({ children }: PropsWithChildren) => {
  const { adminClient } = useAdminClient();
  const { environment } = useEnvironment();
  const [key, setKey] = useState(0);
  const refresh = () => setKey(key + 1);
  const [realmRepresentation, setRealmRepresentation] =
    useState<RealmRepresentation>();

  const routeMatch = useMatch({
    path: DashboardRouteWithRealm.path,
    end: false,
  });

  const realm = routeMatch?.params.realm ?? environment.realm;

  // Configure admin client to use selected realm when it changes.
  useEffect(() => {
    (async () => {
      adminClient.setConfig({ realmName: realm });
      const namespace = encodeURIComponent(realm);
      await getI18n().loadNamespaces(namespace);
      getI18n().setDefaultNamespace(namespace);
    })();
  }, [realm]);
  useFetch(
    () => adminClient.realms.findOne({ realm }),
    setRealmRepresentation,
    [realm, key],
  );

  return (
    <RealmContext.Provider value={{ realm, realmRepresentation, refresh }}>
      {children}
    </RealmContext.Provider>
  );
};

export const useRealm = () => useRequiredContext(RealmContext);
