"use client";
import { createContext, useContext, useState, useEffect, useRef, useOptimistic, startTransition, } from "react";
import { NavigationStoreContext } from "./context.js";
/**
 * Context for Link component to provide its destination URL
 * Used by useLinkStatus to determine if this specific link is pending
 */
export const LinkContext = createContext(null);
/**
 * Normalize URL for comparison
 * Handles relative URLs and ensures consistent format
 */
function normalizeUrl(url, origin) {
    try {
        const parsed = new URL(url, origin);
        // Return pathname + search + hash for comparison
        return parsed.pathname + parsed.search + parsed.hash;
    }
    catch {
        return url;
    }
}
/**
 * Check if this link's destination matches the pending navigation URL
 */
function isPendingFor(linkTo, pendingUrl, origin) {
    if (linkTo === null || pendingUrl === null) {
        return false;
    }
    return normalizeUrl(pendingUrl, origin) === normalizeUrl(linkTo, origin);
}
/**
 * Hook to track the pending state of a Link component
 *
 * Must be used inside a Link component. Returns `{ pending: true }`
 * when navigation to this link's destination is in progress.
 *
 * Useful for showing inline loading indicators on individual links.
 *
 * @example
 * ```tsx
 * function LoadingIndicator() {
 *   const { pending } = useLinkStatus();
 *   return pending ? <Spinner /> : null;
 * }
 *
 * // In your component:
 * <Link to="/dashboard">
 *   Dashboard
 *   <LoadingIndicator />
 * </Link>
 * ```
 */
export function useLinkStatus() {
    const linkTo = useContext(LinkContext);
    const ctx = useContext(NavigationStoreContext);
    // Get origin for URL normalization (stable across renders)
    const origin = typeof window !== "undefined"
        ? window.location.origin
        : "http://localhost";
    // Base state for useOptimistic
    const [basePending, setBasePending] = useState(() => {
        if (!ctx || linkTo === null) {
            return false;
        }
        const state = ctx.eventController.getState();
        return isPendingFor(linkTo, state.pendingUrl, origin);
    });
    const prevPending = useRef(basePending);
    // useOptimistic allows immediate updates during transitions
    const [pending, setOptimisticPending] = useOptimistic(basePending);
    useEffect(() => {
        if (!ctx || linkTo === null) {
            return;
        }
        // Subscribe to navigation state changes
        return ctx.eventController.subscribe(() => {
            const state = ctx.eventController.getState();
            const isPending = isPendingFor(linkTo, state.pendingUrl, origin);
            if (isPending !== prevPending.current) {
                prevPending.current = isPending;
                // Use optimistic update for immediate feedback during navigation
                if (state.state !== "idle") {
                    startTransition(() => {
                        setOptimisticPending(isPending);
                    });
                }
                // Always update base state
                setBasePending(isPending);
            }
        });
    }, [linkTo, origin]);
    // If not inside a Link, return not pending
    if (linkTo === null) {
        return { pending: false };
    }
    return { pending };
}
//# sourceMappingURL=use-link-status.js.map