import { useLingui } from "@lingui/react";
import * as React$1 from "react";
import { jsx } from "react/jsx-runtime";
import { DirectionProvider } from "@cloudflare/kumo/primitives";

//#region src/locales/locales.ts
/**
* All locales that have (or should have) a PO catalog.
* First entry is the source/default locale.
*/
const LOCALES = [
	{
		code: "en",
		label: "English",
		enabled: true
	},
	{
		code: "ar",
		label: "العربية",
		enabled: true,
		dir: "rtl"
	},
	{
		code: "eu",
		label: "Euskara",
		enabled: true
	},
	{
		code: "zh-CN",
		label: "简体中文",
		enabled: true
	},
	{
		code: "zh-TW",
		label: "繁體中文",
		enabled: true
	},
	{
		code: "en-GB",
		label: "English (UK)",
		enabled: true
	},
	{
		code: "fa",
		label: "فارسی",
		enabled: true,
		dir: "rtl"
	},
	{
		code: "fr",
		label: "Français",
		enabled: true
	},
	{
		code: "de",
		label: "Deutsch",
		enabled: true
	},
	{
		code: "id",
		label: "Bahasa Indonesia",
		enabled: true
	},
	{
		code: "ja",
		label: "日本語",
		enabled: true
	},
	{
		code: "ko",
		label: "한국어",
		enabled: false
	},
	{
		code: "nb",
		label: "Norsk bokmål",
		enabled: true
	},
	{
		code: "pl",
		label: "Polski",
		enabled: true
	},
	{
		code: "pt-BR",
		label: "Português (Brasil)",
		enabled: true
	},
	{
		code: "es-419",
		label: "Español (Latinoamérica)",
		enabled: true
	},
	{
		code: "es-ES",
		label: "Español (España)",
		enabled: true
	},
	{
		code: "th",
		label: "ไทย",
		enabled: true
	},
	{
		code: "pseudo",
		label: "Pseudo",
		enabled: false
	}
];
/** The source locale (first entry). */
const SOURCE_LOCALE = LOCALES[0];
/** All locale codes (for Lingui extraction / Lunaria tracking). */
const LOCALE_CODES = LOCALES.map((l) => l.code);
/** Target locales -- everything except the source (for Lunaria). */
const TARGET_LOCALES = LOCALES.slice(1);
/** Locales enabled in the admin UI. */
const ENABLED_LOCALES = LOCALES.filter((l) => l.enabled);

//#endregion
//#region src/locales/config.ts
/**
* Locale configuration for the admin UI runtime.
*
* Locale definitions are in `./locales.ts` -- the single source of truth
* shared by this file, lingui.config.ts and lunaria.config.ts.
*/
function isValidLocale(code) {
	try {
		return new Intl.Locale(code).baseName !== "";
	} catch {
		if (import.meta.env.DEV) throw new Error(`Invalid locale code: "${code}"`);
		return false;
	}
}
/**
* The pseudo locale, injected into the supported list only when
* EMDASH_PSEUDO_LOCALE=1 is set. Never available in production.
*/
const PSEUDO_LOCALE = typeof __EMDASH_PSEUDO_LOCALE__ !== "undefined" && __EMDASH_PSEUDO_LOCALE__ ? LOCALES.find((l) => l.code === "pseudo") : void 0;
/** Available locales at runtime, validated against BCP 47. */
const SUPPORTED_LOCALES = [...ENABLED_LOCALES.filter((l) => isValidLocale(l.code)), ...PSEUDO_LOCALE ? [PSEUDO_LOCALE] : []];
const SUPPORTED_LOCALE_CODES = new Set(SUPPORTED_LOCALES.map((l) => l.code));
const DEFAULT_LOCALE = SOURCE_LOCALE.code;
/** Maps base language codes to supported locales (e.g. "pt" -> "pt-BR"). */
const BASE_LANGUAGE_MAP = /* @__PURE__ */ new Map();
/** Maps script codes to supported locales (e.g. "zh-Hant" -> "zh-TW", "zh-Hans" -> "zh-CN"). */
const SCRIPT_LANGUAGE_MAP = /* @__PURE__ */ new Map();
for (const l of SUPPORTED_LOCALES) {
	const base = l.code.split("-")[0].toLowerCase();
	if (!BASE_LANGUAGE_MAP.has(base)) BASE_LANGUAGE_MAP.set(base, l.code);
	const maximized = new Intl.Locale(l.code).maximize();
	if (maximized.script) {
		const scriptKey = `${maximized.language}-${maximized.script}`.toLowerCase();
		if (!SCRIPT_LANGUAGE_MAP.has(scriptKey)) SCRIPT_LANGUAGE_MAP.set(scriptKey, l.code);
	}
}
/**
* Find the best matching supported locale for a BCP 47 tag.
* Canonicalizes via Intl.Locale so case differences (e.g. "pt-br" vs "pt-BR")
* don't prevent matching. Supports script codes (zh-Hant -> zh-TW, zh-Hans -> zh-CN)
* and falls back to base language (pt-PT -> pt-BR).
*/
function matchLocale(tag) {
	const trimmed = tag.trim();
	if (!trimmed) return void 0;
	let canonical;
	try {
		canonical = new Intl.Locale(trimmed).baseName;
	} catch {
		return;
	}
	if (SUPPORTED_LOCALE_CODES.has(canonical)) return canonical;
	const locale = new Intl.Locale(trimmed);
	if (locale.script) {
		const scriptKey = `${locale.language}-${locale.script}`.toLowerCase();
		const scriptMatch = SCRIPT_LANGUAGE_MAP.get(scriptKey);
		if (scriptMatch) return scriptMatch;
	}
	const base = canonical.split("-")[0].toLowerCase();
	return BASE_LANGUAGE_MAP.get(base);
}
const LOCALE_LABELS = new Map(SUPPORTED_LOCALES.map((l) => [l.code, l.label]));
/** Get a display label for a locale code, falling back to uppercase code. */
function getLocaleLabel(code) {
	return LOCALE_LABELS.get(code) ?? code.toUpperCase();
}
const LOCALE_DIRS = new Map(SUPPORTED_LOCALES.map((l) => [l.code, l.dir]));
/** Get the text direction for a locale code. Defaults to "ltr" if not specified. */
function getLocaleDir(code) {
	return LOCALE_DIRS.get(code) ?? "ltr";
}
const LOCALE_COOKIE_RE = /(?:^|;\s*)emdash-locale=([^;]+)/;
/**
* Resolve the admin locale from a Request.
* Priority: emdash-locale cookie -> Accept-Language -> DEFAULT_LOCALE.
*/
function resolveLocale(request) {
	const cookieLocale = (request.headers.get("cookie") ?? "").match(LOCALE_COOKIE_RE)?.[1]?.trim() ?? "";
	if (SUPPORTED_LOCALE_CODES.has(cookieLocale)) return cookieLocale;
	const acceptLang = request.headers.get("accept-language") ?? "";
	for (const entry of acceptLang.split(",")) {
		const matched = matchLocale(entry.split(";")[0].trim());
		if (matched) return matched;
	}
	return DEFAULT_LOCALE;
}

//#endregion
//#region src/locales/loadMessages.ts
const LOCALE_LOADERS = /* @__PURE__ */ Object.assign({
	"./ar/messages.mjs": () => import("./messages-8fTMJtWA.js"),
	"./de/messages.mjs": () => import("./messages-umZ9RCq_.js"),
	"./en/messages.mjs": () => import("./messages-Cl5m9q7M.js"),
	"./en-GB/messages.mjs": () => import("./messages-otHOIv0j.js"),
	"./es-419/messages.mjs": () => import("./messages-DxYrdNN-.js"),
	"./es-ES/messages.mjs": () => import("./messages-BT9Q9atq.js"),
	"./eu/messages.mjs": () => import("./messages-FkTGnwV-.js"),
	"./fa/messages.mjs": () => import("./messages-CIm8G_NT.js"),
	"./fr/messages.mjs": () => import("./messages-BXAjXbUr.js"),
	"./id/messages.mjs": () => import("./messages-DlzFD1ts.js"),
	"./ja/messages.mjs": () => import("./messages-cWzWbWxk.js"),
	"./ko/messages.mjs": () => import("./messages-Bh2bSu3x.js"),
	"./nb/messages.mjs": () => import("./messages-n6HQSjDA.js"),
	"./pl/messages.mjs": () => import("./messages-BdciNNnG.js"),
	"./pseudo/messages.mjs": () => import("./messages-DjQX9PJY.js"),
	"./pt-BR/messages.mjs": () => import("./messages-B43-WzBC.js"),
	"./th/messages.mjs": () => import("./messages-Crei9McK.js"),
	"./zh-CN/messages.mjs": () => import("./messages-D6wHPGil.js"),
	"./zh-TW/messages.mjs": () => import("./messages-BTDhbVyJ.js")
});
async function loadMessages(locale) {
	const key = `./${locale}/messages.mjs`;
	const fallbackKey = `./${DEFAULT_LOCALE}/messages.mjs`;
	const loader = LOCALE_LOADERS[key] ?? LOCALE_LOADERS[fallbackKey];
	if (!loader) throw new Error(`No locale catalog found for "${locale}" or "${DEFAULT_LOCALE}". Run \`pnpm locale:compile\` to generate catalogs.`);
	const { messages } = await loader();
	return messages;
}

//#endregion
//#region src/locales/useLocale.ts
function setCookie(code) {
	const secure = window.location.protocol === "https:" ? "; Secure" : "";
	document.cookie = `emdash-locale=${code}; Path=/_emdash; SameSite=Lax; Max-Age=31536000${secure}`;
}
/**
* Get the current locale and a function to switch locales.
* Loads the new catalog dynamically and sets a cookie for server-side persistence.
*/
function useLocale() {
	const { i18n } = useLingui();
	const [locale, setLocaleState] = React$1.useState(i18n.locale);
	const setLocale = React$1.useCallback((code) => {
		if (code === i18n.locale || !SUPPORTED_LOCALE_CODES.has(code)) return;
		setCookie(code);
		loadMessages(code).then((messages) => i18n.loadAndActivate({
			locale: code,
			messages
		})).catch(() => {
			setCookie(i18n.locale);
		});
	}, [i18n]);
	React$1.useEffect(() => {
		return i18n.on("change", () => {
			setLocaleState(i18n.locale);
		});
	}, [i18n]);
	return {
		locale,
		setLocale
	};
}

//#endregion
//#region src/locales/LocaleDirectionProvider.tsx
/**
* Wraps the app with DirectionProvider and keeps it in sync with the current locale.
* Automatically updates direction when locale changes via useLocale.
*/
function LocaleDirectionProvider({ children }) {
	const { locale } = useLocale();
	const dir = React$1.useMemo(() => getLocaleDir(locale), [locale]);
	/** Sync the direction and lang attributes with the current locale. */
	React$1.useEffect(() => {
		document.documentElement.setAttribute("lang", locale);
		document.documentElement.setAttribute("dir", dir);
	}, [dir, locale]);
	return /* @__PURE__ */ jsx(DirectionProvider, {
		direction: dir,
		children
	});
}

//#endregion
export { SUPPORTED_LOCALES as a, getLocaleLabel as c, DEFAULT_LOCALE as i, resolveLocale as l, useLocale as n, SUPPORTED_LOCALE_CODES as o, loadMessages as r, getLocaleDir as s, LocaleDirectionProvider as t };
//# sourceMappingURL=LocaleDirectionProvider-CK7aJ2Lb.js.map