import { serializeSearchParams } from "./search-params.js";
/**
 * Get a locally-typed reverse function from ctx.reverse for composable modules.
 *
 * This is a type-only cast - ctx.reverse already resolves local names at runtime
 * based on the current route prefix. This helper just provides type safety
 * for local route names within a url module.
 *
 * @param reverse - The ctx.reverse function from HandlerContext
 * @returns The same reverse function, but typed for local routes
 *
 * @example
 * ```typescript
 * // urls/blog.tsx
 * export const blogPatterns = urls(({ path }) => [
 *   path("/", (ctx) => {
 *     // Get locally-typed reverse for this module's routes
 *     const reverse = scopedReverse<typeof blogPatterns>(ctx.reverse);
 *
 *     reverse("index");              // ✓ Type-safe local route
 *     reverse("post", { slug: "x" }); // ✓ Type-safe with params
 *     reverse("shop.cart");          // ✓ Type-safe global route
 *
 *     return <BlogIndex />;
 *   }, { name: "index" }),
 *
 *   path("/:slug", BlogPost, { name: "post" }),
 * ]);
 * ```
 */
export function scopedReverse(reverse) {
    return reverse;
}
function resolveRoutePattern(entry) {
    if (!entry)
        return undefined;
    return typeof entry === "string" ? entry : entry.path;
}
export function createReverse(routeMap, getFallbackMap) {
    return ((name, params, search) => {
        let pattern = resolveRoutePattern(routeMap[name]);
        if (!pattern) {
            // Try the static route names from the generated file (O(1) fallback)
            const fallback = getFallbackMap?.();
            if (fallback) {
                pattern = resolveRoutePattern(fallback[name]);
            }
        }
        if (!pattern) {
            // During build-time discovery, lazy includes haven't resolved yet.
            // Return a placeholder instead of crashing the build.
            if (globalThis.__rscRouterDiscoveryActive) {
                return `/__unresolved_reverse/${name}`;
            }
            throw new Error(`Unknown route: ${name}`);
        }
        let result = pattern;
        if (params) {
            // Replace :param placeholders with actual values
            result = result.replace(/:([^/]+)/g, (_, key) => {
                const value = params[key];
                if (value === undefined) {
                    throw new Error(`Missing param "${key}" for route "${name}"`);
                }
                return encodeURIComponent(value);
            });
        }
        // Append search params as query string
        if (search) {
            const qs = serializeSearchParams(search);
            if (qs) {
                result += `?${qs}`;
            }
        }
        return result;
    });
}
//# sourceMappingURL=reverse.js.map