/**
 * Navigation-aware request cancellation context.
 *
 * Provides a global cancellation mechanism tied to route transitions.
 * When the user navigates to a new route, all AbortSignals whose associated
 * pathname no longer matches the current route are automatically aborted,
 * cancelling in-flight requests associated with the previous route.
 *
 * Design:
 * - Each request is associated with the pathname that was active when it started.
 * - On navigation, all controllers for the old pathname are aborted.
 * - Requests can opt out of cancellation by setting `ignoreCancellation: true`.
 * - Background tasks (polling, long-lived syncs) should opt out.
 *
 * Long-lived background fetches (e.g., polling with long TTL) can opt-out
 * by not using this context and instead managing their own lifecycle,
 * or by checking the signal early in their lifecycle.
 */

import { createContext } from "react";

/**
 * Options for getNavigationSignal().
 */
export interface GetNavigationSignalOptions {
  /**
   * If true, the signal will not be aborted on navigation.
   * Use for background tasks that should survive route changes.
   *
   * @default false
   */
  ignoreCancellation?: boolean;
}

/**
 * Provides a fresh AbortSignal tied to the current route lifecycle.
 *
 * Each call returns a new AbortSignal. When the user navigates,
 * all previously-returned signals are aborted.
 */
export interface NavigationCancellationContextType {
  /**
   * Get an AbortSignal for the current route's request lifecycle.
   *
   * The signal will be aborted automatically when the user navigates
   * to a different route. This is ideal for route-specific data fetches
   * that should not persist across page transitions.
   *
   * @param options - Optional configuration for the signal
   * @param options.ignoreCancellation - If true, the signal will not be
   *   aborted on navigation. Use for background tasks that should survive
   *   route changes.
   *
   * @returns An AbortSignal that lives for the duration of the current route
   */
  getNavigationSignal(options?: GetNavigationSignalOptions): AbortSignal;
}

/**
 * React context for navigation-aware cancellation.
 *
 * Wrap the application with `NavigationCancellationProvider` to enable
 * automatic request cancellation on route transitions.
 */
export const NavigationCancellationContext =
  createContext<NavigationCancellationContextType | null>(null);

NavigationCancellationContext.displayName = "NavigationCancellation";
