const require_rolldown_runtime = require('../_virtual/rolldown_runtime.cjs');
const require_proxy_localeDetector = require('./localeDetector.cjs');
let __intlayer_config_built = require("@intlayer/config/built");
__intlayer_config_built = require_rolldown_runtime.__toESM(__intlayer_config_built);
let __intlayer_core = require("@intlayer/core");
let __intlayer_config_client = require("@intlayer/config/client");
let next_server = require("next/server");

//#region src/proxy/intlayerProxy.ts
const { internationalization, routing } = __intlayer_config_built.default ?? {};
const { locales, defaultLocale } = internationalization ?? {};
const { basePath, mode } = routing ?? {};
const effectiveMode = mode ?? __intlayer_config_client.DefaultValues.Routing.ROUTING_MODE;
const noPrefix = effectiveMode === "no-prefix" || effectiveMode === "search-params";
const prefixDefault = effectiveMode === "prefix-all";
/**
* Detects if the request is a prefetch request from Next.js.
*
* Next.js prefetch requests can be identified by several headers:
* - purpose: 'prefetch' (standard prefetch header)
* - next-router-prefetch: '1' (Next.js router prefetch)
* - next-url: present (Next.js internal navigation)
*
* During prefetch, we should ignore cookie-based locale detection
* to prevent unwanted redirects when users are switching locales.
*
* @param request - The incoming Next.js request object.
* @returns - True if the request is a prefetch request, false otherwise.
*/
const isPrefetchRequest = (request) => {
	const purpose = request.headers.get("purpose");
	const nextRouterPrefetch = request.headers.get("next-router-prefetch");
	const nextUrl = request.headers.get("next-url");
	const xNextjsData = request.headers.get("x-nextjs-data");
	return purpose === "prefetch" || nextRouterPrefetch === "1" || !!nextUrl || !!xNextjsData;
};
const appendLocaleSearchIfNeeded = (search, locale) => {
	if (effectiveMode !== "search-params") return search;
	const params = new URLSearchParams(search ?? "");
	params.set("locale", locale);
	return `?${params.toString()}`;
};
/**
* Proxy that handles the internationalization layer
*
* Usage:
*
* ```ts
* // ./src/proxy.ts
*
* export { intlayerProxy as proxy } from '@intlayer/next/proxy';
*
* // applies this proxy only to files in the app directory
* export const config = {
*   matcher: '/((?!api|static|.*\\..*|_next).*)',
* };
* ```
*
* Main proxy function for handling internationalization.
*
* @param request - The incoming Next.js request object.
* @param event - The Next.js fetch event (optional).
* @param response - The Next.js response object (optional).
* @returns - The response to be returned to the client.
*/
const intlayerProxy = (request, _event, _response) => {
	const pathname = request.nextUrl.pathname;
	const localLocale = getLocalLocale(request);
	if (noPrefix) return handleNoPrefix(request, localLocale, pathname);
	return handlePrefix(request, localLocale, getPathLocale(pathname), pathname);
};
/**
* Retrieves the locale from the request cookies if available and valid.
*
* @param request - The incoming Next.js request object.
* @returns - The locale found in the cookies, or undefined if not found or invalid.
*/
const getLocalLocale = (request) => (0, __intlayer_core.getLocaleFromStorage)({
	getCookie: (name) => request.cookies.get(name)?.value ?? null,
	getHeader: (name) => request.headers.get(name) ?? null
});
/**
* Handles the case where URLs do not have locale prefixes.
*
* @param request - The incoming Next.js request object.
* @param localLocale - The locale from the cookie.
* @param pathname - The pathname from the request URL.
* @returns - The rewritten response with the locale applied.
*/
const handleNoPrefix = (request, localLocale, pathname) => {
	const pathLocale = getPathLocale(pathname);
	if (pathLocale) {
		const pathWithoutLocale = pathname.slice(`/${pathLocale}`.length) || "/";
		const search$1 = appendLocaleSearchIfNeeded(request.nextUrl.search, pathLocale);
		return redirectUrl(request, search$1 ? `${pathWithoutLocale}${search$1}` : `${pathWithoutLocale}${request.nextUrl.search ?? ""}`);
	}
	const locale = localLocale ?? defaultLocale;
	if (effectiveMode === "search-params") {
		if (new URLSearchParams(request.nextUrl.search).get("locale") === locale) return rewriteUrl(request, `${`/${locale}${pathname}`}${request.nextUrl.search ?? ""}`, locale);
		const search$1 = appendLocaleSearchIfNeeded(request.nextUrl.search, locale);
		return redirectUrl(request, search$1 ? `${pathname}${search$1}` : `${pathname}${request.nextUrl.search ?? ""}`);
	}
	const internalPath = `/${locale}${pathname}`;
	const search = appendLocaleSearchIfNeeded(request.nextUrl.search, locale);
	return rewriteUrl(request, search ? `${internalPath}${search}` : `${internalPath}${request.nextUrl.search ?? ""}`, locale);
};
/**
* Extracts the locale from the URL pathname if present.
*
* @param pathname - The pathname from the request URL.
* @returns - The locale found in the pathname, or undefined if not found.
*/
const getPathLocale = (pathname) => locales.find((locale) => pathname.startsWith(`/${locale}/`) || pathname === `/${locale}`);
/**
* Handles the case where URLs have locale prefixes.
*
* @param request - The incoming Next.js request object.
* @param localLocale - The locale from the cookie.
* @param pathLocale - The locale extracted from the pathname.
* @param pathname - The pathname from the request URL.
* @param basePathTrailingSlash - Indicates if the basePath ends with a slash.
* @returns - The response to be returned to the client.
*/
const handlePrefix = (request, localLocale, pathLocale, pathname) => {
	if (!pathLocale) {
		if (isPrefetchRequest(request) && true) return handleMissingPathLocale(request, defaultLocale, pathname);
		return handleMissingPathLocale(request, localLocale, pathname);
	}
	return handleExistingPathLocale(request, localLocale, pathLocale, pathname);
};
/**
* Handles requests where the locale is missing from the URL pathname.
*
* @param request - The incoming Next.js request object.
* @param localLocale - The locale from the cookie.
* @param pathname - The pathname from the request URL.
* @param basePathTrailingSlash - Indicates if the basePath ends with a slash.
* @returns - The response to be returned to the client.
*/
const handleMissingPathLocale = (request, localLocale, pathname) => {
	let locale = localLocale ?? require_proxy_localeDetector.localeDetector?.(request) ?? defaultLocale;
	if (!locales.includes(locale)) locale = defaultLocale;
	const newPath = constructPath(locale, pathname, basePath, appendLocaleSearchIfNeeded(request.nextUrl.search, locale));
	return prefixDefault || locale !== defaultLocale ? redirectUrl(request, newPath) : rewriteUrl(request, newPath, locale);
};
/**
* Handles requests where the locale exists in the URL pathname.
*
* @param request - The incoming Next.js request object.
* @param localLocale - The locale from the cookie.
* @param pathLocale - The locale extracted from the pathname.
* @param pathname - The pathname from the request URL.
* @returns - The response to be returned to the client.
*/
const handleExistingPathLocale = (request, localLocale, pathLocale, pathname) => {
	if (localLocale && localLocale !== pathLocale) return redirectUrl(request, handleCookieLocaleMismatch(request, pathname, pathLocale, localLocale, basePath));
	return handleDefaultLocaleRedirect(request, pathLocale, pathname);
};
/**
* Handles the scenario where the locale in the cookie does not match the locale in the URL pathname.
*
* @param request - The incoming Next.js request object.
* @param pathname - The pathname from the request URL.
* @param pathLocale - The locale extracted from the pathname.
* @param localLocale - The locale from the cookie.
* @param basePath - The base path of the application.
* @returns - The new URL path with the correct locale.
*/
const handleCookieLocaleMismatch = (request, pathname, pathLocale, localLocale, basePath$1) => {
	return constructPath(localLocale, pathname.replace(`/${pathLocale}`, `/${localLocale}`), basePath$1, appendLocaleSearchIfNeeded(request.nextUrl.search, localLocale));
};
/**
* Handles redirection when the default locale is used and prefixing is not required.
*
* @param request - The incoming Next.js request object.
* @param pathLocale - The locale extracted from the pathname.
* @param pathname - The pathname from the request URL.
* @returns - The rewritten response without the locale prefix.
*/
const handleDefaultLocaleRedirect = (request, pathLocale, pathname) => {
	if (!prefixDefault && pathLocale === defaultLocale) {
		let pathWithoutLocale = pathname.slice(`/${pathLocale}`.length) ?? "/";
		if (basePath.endsWith("/")) pathWithoutLocale = pathWithoutLocale.slice(1);
		const searchWithLocale$1 = appendLocaleSearchIfNeeded(request.nextUrl.search, pathLocale);
		if (searchWithLocale$1) pathWithoutLocale += searchWithLocale$1;
		else if (request.nextUrl.search) pathWithoutLocale += request.nextUrl.search;
		return rewriteUrl(request, `${basePath}${pathWithoutLocale}`, pathLocale);
	}
	const searchWithLocale = appendLocaleSearchIfNeeded(request.nextUrl.search, pathLocale);
	return rewriteUrl(request, searchWithLocale ? `${pathname}${searchWithLocale}` : pathname, pathLocale);
};
/**
* Constructs a new path by combining the locale, path, basePath, and search parameters.
*
* @param locale - The locale to include in the path.
* @param path - The original path from the request.
* @param basePath - The base path of the application.
* @param [search] - The query string from the request URL (optional).
* @returns - The constructed new path.
*/
const constructPath = (locale, path, basePath$1, search) => {
	const pathWithoutPrefix = path.startsWith(`/${locale}`) ? path.slice(`/${locale}`.length) || "/" : path;
	if (effectiveMode === "no-prefix") {
		if (search) return `${pathWithoutPrefix}?${search}`;
		return pathWithoutPrefix;
	}
	if (effectiveMode === "search-params") {
		if (search) return `${pathWithoutPrefix}?${search}`;
		return pathWithoutPrefix;
	}
	const pathWithLocalePrefix = path.startsWith(`/${locale}`) ? path : `${locale}${path}`;
	return `${basePath$1}${basePath$1.endsWith("/") ? "" : "/"}${pathWithLocalePrefix}`;
};
/**
* Rewrites the URL to the new path and sets the locale header.
*
* @param request - The incoming Next.js request object.
* @param newPath - The new path to rewrite to.
* @param locale - The locale to set in the response header.
* @returns - The rewritten response.
*/
const rewriteUrl = (request, newPath, locale) => {
	const search = request.nextUrl.search;
	const pathWithSearch = search && !newPath.includes("?") ? `${newPath}${search}` : newPath;
	const response = next_server.NextResponse.rewrite(new URL(pathWithSearch, request.url));
	(0, __intlayer_core.setLocaleInStorage)(locale, { setHeader: (name, value) => response.headers.set(name, value) });
	return response;
};
/**
* Redirects the request to the new path.
*
* @param request - The incoming Next.js request object.
* @param newPath - The new path to redirect to.
* @returns - The redirect response.
*/
const redirectUrl = (request, newPath) => {
	const search = request.nextUrl.search;
	const pathWithSearch = search && !newPath.includes("?") ? `${newPath}${search}` : newPath;
	return next_server.NextResponse.redirect(new URL(pathWithSearch, request.url));
};

//#endregion
exports.intlayerProxy = intlayerProxy;
//# sourceMappingURL=intlayerProxy.cjs.map