import { getRequestConfig } from "next-intl/server";
import { cookies, headers } from "next/headers";
import { auth } from "@/auth";

export const locales = ["en", "de", "fr"] as const;
export type Locale = (typeof locales)[number];
export const defaultLocale: Locale = "en";

function isLocale(v: unknown): v is Locale {
  return typeof v === "string" && (locales as readonly string[]).includes(v);
}

/**
 * Read the `preferred_language` claim from the user's Keycloak access
 * token. The claim is sourced from FreeIPA's `preferredLanguage` user
 * attribute via the gosecCloud realm's LDAP attribute mapper and the
 * per-client OIDC protocol mapper. Returns `undefined` if no session,
 * no claim, or the value isn't in our supported `locales`.
 */
async function localeFromKeycloak(): Promise<Locale | undefined> {
  try {
    const session = await auth();
    const accessToken = (session?.user as { accessToken?: string } | undefined)?.accessToken;
    if (!accessToken) return undefined;
    const payload = accessToken.split(".")[1];
    if (!payload) return undefined;
    const padded = payload + "=".repeat((4 - (payload.length % 4)) % 4);
    const decoded = Buffer.from(padded, "base64").toString("utf8");
    const json = JSON.parse(decoded) as { preferred_language?: string };
    return isLocale(json.preferred_language) ? json.preferred_language : undefined;
  } catch {
    return undefined;
  }
}

export default getRequestConfig(async () => {
  // Resolution order:
  //   1. NEXT_LOCALE cookie  — recent /settings change, beats the
  //      stale token claim until the next refresh.
  //   2. Keycloak `preferred_language` claim — FreeIPA-backed
  //      durable preference.
  //   3. Accept-Language header.
  //   4. defaultLocale.
  const cookieStore = await cookies();
  const cookieLocale = cookieStore.get("NEXT_LOCALE")?.value;

  let locale: Locale | undefined = isLocale(cookieLocale) ? cookieLocale : undefined;

  if (!locale) {
    locale = await localeFromKeycloak();
  }

  if (!locale) {
    const headersList = await headers();
    const acceptLanguage = headersList.get("accept-language");
    if (acceptLanguage) {
      const candidate = acceptLanguage.split(",")[0]?.split("-")[0];
      if (isLocale(candidate)) locale = candidate;
    }
  }

  if (!locale) locale = defaultLocale;

  return {
    locale,
    messages: (await import(`../../public/locales/${locale}/common.json`)).default,
    onError(error) {
      if (error.code === "MISSING_MESSAGE") {
        console.warn(error.message);
      } else {
        console.error(error);
      }
    },
    getMessageFallback({ key }) {
      return key;
    },
  };
});
