import { RouteContext } from "./RouteContext.js";
import { useWindowEventListener } from "../hooks/useWindowEventListener.js";
import { newPaths } from "./newPaths.js";
import { match } from "./pathToRegexp.js";
import { Route } from "./Route.js";
import React from "react";
import { useClerk } from "@clerk/shared/react";
import { jsx } from "@emotion/react/jsx-runtime";
import { trimTrailingSlash } from "@clerk/shared/internal/clerk-js/url";
import { getQueryParams, stringifyQueryParams } from "@clerk/shared/internal/clerk-js/querystring";
import { flushSync } from "react-dom";

//#region src/router/BaseRouter.tsx
const BaseRouter = ({ basePath, startPath, getPath, getQueryString, internalNavigate, refreshEvents, preservedParams, urlStateParam, children }) => {
	const { navigate: clerkNavigate } = useClerk();
	const [routeParts, setRouteParts] = React.useState({
		path: getPath(),
		queryString: getQueryString()
	});
	const currentPath = routeParts.path;
	const currentQueryString = routeParts.queryString;
	const currentQueryParams = getQueryParams(routeParts.queryString);
	const resolve = (to) => {
		return new URL(to, window.location.origin);
	};
	const getMatchData = (path, index) => {
		const [newIndexPath, newFullPath] = newPaths("", "", path, index);
		const currentPathWithoutSlash = trimTrailingSlash(currentPath);
		const matchResult = path && match(newFullPath + "/:foo*")(currentPathWithoutSlash) || index && match(newIndexPath)(currentPathWithoutSlash) || index && match(newFullPath)(currentPathWithoutSlash) || false;
		if (matchResult !== false) return matchResult.params;
		else return false;
	};
	const matches = (path, index) => {
		return !!getMatchData(path, index);
	};
	const refresh = React.useCallback(() => {
		const newPath = getPath();
		const newQueryString = getQueryString();
		if (newPath !== currentPath || newQueryString !== currentQueryString) setRouteParts({
			path: newPath,
			queryString: newQueryString
		});
	}, [
		currentPath,
		currentQueryString,
		getPath,
		getQueryString
	]);
	useWindowEventListener(refreshEvents, refresh);
	const baseNavigate = async (toURL) => {
		if (!toURL) return;
		const isCrossOrigin = toURL.origin !== window.location.origin;
		if (!toURL.pathname.startsWith("/" + basePath) || isCrossOrigin) {
			const res = await clerkNavigate(toURL.href);
			refresh();
			return res;
		}
		if (preservedParams) {
			const toQueryParams = getQueryParams(toURL.search);
			preservedParams.forEach((param) => {
				if (!toQueryParams[param] && currentQueryParams[param]) toQueryParams[param] = currentQueryParams[param];
			});
			toURL.search = stringifyQueryParams(toQueryParams);
		}
		const internalNavRes = await internalNavigate(toURL, { metadata: { navigationType: "internal" } });
		flushSync(() => {
			setRouteParts({
				path: toURL.pathname,
				queryString: toURL.search
			});
		});
		return internalNavRes;
	};
	return /* @__PURE__ */ jsx(RouteContext.Provider, {
		value: {
			basePath,
			startPath,
			flowStartPath: startPath,
			fullPath: "",
			indexPath: "",
			currentPath,
			queryString: currentQueryString,
			queryParams: currentQueryParams,
			getMatchData: getMatchData.bind(void 0),
			matches: matches.bind(void 0),
			baseNavigate: baseNavigate.bind(void 0),
			navigate: async () => {},
			resolve: resolve.bind(void 0),
			refresh: refresh.bind(void 0),
			params: {},
			urlStateParam
		},
		children: /* @__PURE__ */ jsx(Route, {
			path: basePath,
			children
		})
	});
};

//#endregion
export { BaseRouter };
//# sourceMappingURL=BaseRouter.js.map