import * as Solid from 'solid-js';
import { replaceEqualDeep, rootRouteId } from '@tanstack/router-core';
import { isServer } from '@tanstack/router-core/isServer';
import { CatchBoundary, ErrorComponent } from './CatchBoundary';
import { useRouter } from './useRouter';
import { Transitioner } from './Transitioner';
import { nearestMatchContext } from './matchContext';
import { SafeFragment } from './SafeFragment';
import { Match } from './Match';
export function Matches() {
    const router = useRouter();
    const ResolvedSuspense = (isServer ?? router.isServer) ||
        (typeof document !== 'undefined' && router.ssr)
        ? SafeFragment
        : Solid.Suspense;
    const rootRoute = () => router.routesById[rootRouteId];
    const PendingComponent = rootRoute().options.pendingComponent ??
        router.options.defaultPendingComponent;
    const OptionalWrapper = router.options.InnerWrap || SafeFragment;
    return (<OptionalWrapper>
      <ResolvedSuspense fallback={PendingComponent ? <PendingComponent /> : null}>
        <Transitioner />
        <MatchesInner />
      </ResolvedSuspense>
    </OptionalWrapper>);
}
function MatchesInner() {
    const router = useRouter();
    const matchId = () => router.stores.firstMatchId.state;
    const routeId = () => (matchId() ? rootRouteId : undefined);
    const match = () => routeId()
        ? router.stores.getMatchStoreByRouteId(rootRouteId).state
        : undefined;
    const hasPendingMatch = () => routeId()
        ? Boolean(router.stores.pendingRouteIds.state[rootRouteId])
        : false;
    const resetKey = () => router.stores.loadedAt.state;
    const nearestMatch = {
        matchId,
        routeId,
        match,
        hasPending: hasPendingMatch,
    };
    const matchComponent = () => {
        return (<Solid.Show when={matchId()}>
        <Match matchId={matchId()}/>
      </Solid.Show>);
    };
    return (<nearestMatchContext.Provider value={nearestMatch}>
      {router.options.disableGlobalCatchBoundary ? (matchComponent()) : (<CatchBoundary getResetKey={() => resetKey()} errorComponent={ErrorComponent} onCatch={process.env.NODE_ENV !== 'production'
                ? (error) => {
                    console.warn(`Warning: The following error wasn't caught by any route! At the very least, consider setting an 'errorComponent' in your RootRoute!`);
                    console.warn(`Warning: ${error.message || error.toString()}`);
                }
                : undefined}>
          {matchComponent()}
        </CatchBoundary>)}
    </nearestMatchContext.Provider>);
}
export function useMatchRoute() {
    const router = useRouter();
    return (opts) => {
        return Solid.createMemo(() => {
            const { pending, caseSensitive, fuzzy, includeSearch, ...rest } = opts;
            router.stores.matchRouteReactivity.state;
            return router.matchRoute(rest, {
                pending,
                caseSensitive,
                fuzzy,
                includeSearch,
            });
        });
    };
}
export function MatchRoute(props) {
    const matchRoute = useMatchRoute();
    const params = matchRoute(props);
    const renderedChild = Solid.createMemo(() => {
        const matchedParams = params();
        const child = props.children;
        if (typeof child === 'function') {
            return child(matchedParams);
        }
        return matchedParams ? child : null;
    });
    return <>{renderedChild()}</>;
}
export function useMatches(opts) {
    const router = useRouter();
    return Solid.createMemo((prev) => {
        const matches = router.stores.activeMatchesSnapshot.state;
        const res = opts?.select ? opts.select(matches) : matches;
        if (prev === undefined)
            return res;
        return replaceEqualDeep(prev, res);
    });
}
export function useParentMatches(opts) {
    const contextMatchId = Solid.useContext(nearestMatchContext).matchId;
    return useMatches({
        select: (matches) => {
            matches = matches.slice(0, matches.findIndex((d) => d.id === contextMatchId()));
            return opts?.select ? opts.select(matches) : matches;
        },
    });
}
export function useChildMatches(opts) {
    const contextMatchId = Solid.useContext(nearestMatchContext).matchId;
    return useMatches({
        select: (matches) => {
            matches = matches.slice(matches.findIndex((d) => d.id === contextMatchId()) + 1);
            return opts?.select ? opts.select(matches) : matches;
        },
    });
}
//# sourceMappingURL=Matches.jsx.map