/**
 * Route configuration hook for type-safe custom route injection.
 *
 * Use this hook to register custom routes, navigation links, and
 * route guards from within your components.
 *
 * @generated by Prism — GENERATE_ONCE (safe to edit)
 */

import { type ReactElement, createContext, useContext, useState, useCallback, useMemo } from 'react';
import type { RouteObject } from 'react-router-dom';

/** A navigation link entry for the sidebar */
export interface NavLink {
  /** URL path */
  path: string;
  /** Display label */
  label: string;
  /** Optional SVG icon element */
  icon?: ReactElement;
  /** Sort order (lower = higher in sidebar) */
  order?: number;
}

/** Custom route with optional metadata */
export type CustomRoute = RouteObject & {
  /** Navigation link for this route (omit to hide from nav) */
  nav?: Omit<NavLink, 'path'>;
};

interface RouteConfigContextValue {
  /** Registered custom routes */
  routes: CustomRoute[];
  /** Registered navigation links */
  navLinks: NavLink[];
  /** Register a new route (call in useEffect or module scope) */
  registerRoute: (route: CustomRoute) => void;
  /** Register a navigation link without a route */
  registerNavLink: (link: NavLink) => void;
}

const RouteConfigContext = createContext<RouteConfigContextValue | null>(null);

/**
 * Access route configuration.
 *
 * @example
 * ```tsx
 * const { routes, navLinks, registerRoute } = useRouteConfig();
 * ```
 */
export function useRouteConfig(): RouteConfigContextValue {
  const ctx = useContext(RouteConfigContext);
  if (!ctx) {
    throw new Error('useRouteConfig must be used within a RouteConfigProvider');
  }
  return ctx;
}

/**
 * Provider that manages custom route registration.
 *
 * Wrap your application with this provider to enable dynamic route injection.
 */
export function RouteConfigProvider({ children }: { children: React.ReactNode }): ReactElement {
  const [routes, setRoutes] = useState<CustomRoute[]>([]);
  const [navLinks, setNavLinks] = useState<NavLink[]>([]);

  const registerRoute = useCallback((route: CustomRoute) => {
    setRoutes((prev) => {
      // Avoid duplicates by path
      if (prev.some((r) => r.path === route.path)) return prev;
      return [...prev, route];
    });
    // Auto-register nav link if route has nav metadata
    if (route.nav && route.path) {
      setNavLinks((prev) => {
        if (prev.some((l) => l.path === route.path)) return prev;
        return [...prev, { path: route.path!, ...route.nav! }];
      });
    }
  }, []);

  const registerNavLink = useCallback((link: NavLink) => {
    setNavLinks((prev) => {
      if (prev.some((l) => l.path === link.path)) return prev;
      return [...prev, link];
    });
  }, []);

  const sortedNavLinks = useMemo(
    () => [...navLinks].sort((a, b) => (a.order ?? 100) - (b.order ?? 100)),
    [navLinks],
  );

  const value = useMemo(
    () => ({ routes, navLinks: sortedNavLinks, registerRoute, registerNavLink }),
    [routes, sortedNavLinks, registerRoute, registerNavLink],
  );

  return (
    <RouteConfigContext.Provider value={value}>
      {children}
    </RouteConfigContext.Provider>
  );
}

export default useRouteConfig;
