// src/hooks/useToolUrlRouting.ts
// Focused hook for URL <-> tool-key mapping and browser history sync.

import { useCallback, useEffect, useMemo, useRef, useState } from 'react';

export interface UseToolUrlRoutingOpts {
  /** Currently selected tool key (from context). */
  selectedToolKey: string | null;
  /** Registry of available tools (key -> tool metadata). */
  toolRegistry: Record<string, any> | null | undefined;
  /** Select a tool (no extra side-effects). */
  selectTool: (toolKey: string) => void;
  /** Clear selection. */
  clearToolSelection: () => void;
  /** Called once during initialization if URL contains a tool; may trigger UI changes. */
  onInitSelect?: (toolKey: string) => void;
  /** Called when navigating via back/forward (popstate). Defaults to selectTool. */
  onPopStateSelect?: (toolKey: string) => void;
  /** Optional base path if the app isn't served at "/" (no trailing slash). Default: "" (root). */
  basePath?: string;
}

export function useToolUrlRouting(opts: UseToolUrlRoutingOpts) {
  const {
    selectedToolKey,
    toolRegistry,
    selectTool,
    clearToolSelection,
    onInitSelect,
    onPopStateSelect,
    basePath = '',
  } = opts;

  // Central slug map; keep here to co-locate routing policy.
  const urlMap = useMemo(
    () =>
      new Map<string, string>([
        ['compress', 'compress-pdf'],
        ['split', 'split-pdf'],
        ['convert', 'convert-pdf'],
        ['ocr', 'ocr-pdf'],
        ['merge', 'merge-pdf'],
        ['rotate', 'rotate-pdf'],
      ]),
    []
  );

  const getToolUrlSlug = useCallback(
    (toolKey: string) => urlMap.get(toolKey) ?? toolKey,
    [urlMap]
  );

  const getToolKeyFromSlug = useCallback(
    (slug: string) => {
      for (const [key, value] of urlMap) {
        if (value === slug) return key;
      }
      return slug; // fall back to raw key
    },
    [urlMap]
  );

  // Internal flag to avoid clearing URL on initial mount.
  const [hasInitialized, setHasInitialized] = useState(false);

  // Normalize a pathname by stripping basePath and leading slash.
  const normalizePath = useCallback(
    (fullPath: string) => {
      let p = fullPath;
      if (basePath && p.startsWith(basePath)) {
        p = p.slice(basePath.length);
      }
      if (p.startsWith('/')) p = p.slice(1);
      return p;
    },
    [basePath]
  );

  // Update URL when tool changes (but not on first paint before any selection happens).
  useEffect(() => {
    if (selectedToolKey) {
      const slug = getToolUrlSlug(selectedToolKey);
      const newUrl = `${basePath}/${slug}`.replace(/\/+/, '/');
      window.history.replaceState({}, '', newUrl);
      setHasInitialized(true);
    } else if (hasInitialized) {
      const rootUrl = basePath || '/';
      window.history.replaceState({}, '', rootUrl);
    }
  }, [selectedToolKey, getToolUrlSlug, hasInitialized, basePath]);

  // Initialize from URL when the registry is ready and nothing is selected yet.
  useEffect(() => {
    if (!toolRegistry || Object.keys(toolRegistry).length === 0) return;
    if (selectedToolKey) return; // don't override explicit selection

    const currentPath = normalizePath(window.location.pathname);
    if (currentPath) {
      const toolKey = getToolKeyFromSlug(currentPath);
      if (toolRegistry[toolKey]) {
        (onInitSelect ?? selectTool)(toolKey);
      }
    }
  }, [toolRegistry, selectedToolKey, getToolKeyFromSlug, selectTool, onInitSelect, normalizePath]);

  // Handle browser back/forward. NOTE: useRef needs an initial value in TS.
  const popHandlerRef = useRef<((this: Window, ev: PopStateEvent) => any) | null>(null);

  useEffect(() => {
    popHandlerRef.current = () => {
      const path = normalizePath(window.location.pathname);
      if (path) {
        const toolKey = getToolKeyFromSlug(path);
        if (toolRegistry && toolRegistry[toolKey]) {
          (onPopStateSelect ?? selectTool)(toolKey);
          return;
        }
      }
      clearToolSelection();
    };

    const handler = (e: PopStateEvent) => popHandlerRef.current?.call(window, e);
    window.addEventListener('popstate', handler);
    return () => window.removeEventListener('popstate', handler);
  }, [toolRegistry, selectTool, clearToolSelection, getToolKeyFromSlug, onPopStateSelect, normalizePath]);

  // Expose pure helpers if you want them elsewhere (optional).
  return { getToolUrlSlug, getToolKeyFromSlug };
}
