import { create } from 'zustand';

/**
 * Back-context store, consumed by `useSmartBack` to drive the topbar
 * back button. Three responsibilities:
 *
 *  1. `hints` - per-pathname entity hierarchy registered via
 *     `useBreadcrumbHint` on detail-page mount, used to override the
 *     URL-derived parent (so an interest page's back goes to "Sarah
 *     Doe" instead of "Clients").
 *
 *  2. `historyStack` - in-app navigation history pushed by the
 *     `NavigationHistoryTracker`. When non-empty, the smart-back hook
 *     prefers the top of the stack so cross-record drills (Sarah ->
 *     Yacht -> Back) return to the page the rep was actually on rather
 *     than the logical parent. Survives only the SPA session (in-memory),
 *     so deep-link refresh correctly falls through to the logical
 *     parent.
 *
 *  3. `labelCache` - per-pathname display label captured at hint-
 *     registration time, persisting past page unmount. Lets the back
 *     button render "Back to Sarah Doe" even after Sarah's detail page
 *     has unmounted (which is the normal case when the rep has drilled
 *     into a Yacht from her record).
 *
 * Historical note: this store originally fed a topbar breadcrumb chain
 * which was removed in favor of a single contextual back button. The
 * file and hook names kept their `breadcrumb` prefix to avoid touching
 * the 6 existing detail-page integrations.
 *
 * All keys are pathnames (not entity IDs) so concurrent route mounts
 * don't trample each other under Next's client-side router.
 */
export interface BreadcrumbHintCrumb {
  label: string;
  href?: string;
}

export interface BreadcrumbHint {
  parents: BreadcrumbHintCrumb[];
  current: string;
}

/** Soft cap on the history stack so a long browsing session doesn't
 *  unboundedly grow the in-memory store. 25 is plenty: the back button
 *  only consumes the top of stack, and stacks rarely exceed 4-5 entries
 *  in real-world flows. */
const HISTORY_LIMIT = 25;

interface BreadcrumbStore {
  hints: Record<string, BreadcrumbHint>;
  historyStack: string[];
  labelCache: Record<string, string>;
  setHint: (pathname: string, hint: BreadcrumbHint) => void;
  clearHint: (pathname: string) => void;
  /** Cache a display label for a pathname. Called from
   *  `useBreadcrumbHint` so labels survive page unmount and the back
   *  button can render "Back to Sarah Doe" after navigating away. */
  cacheLabel: (pathname: string, label: string) => void;
  /** Push a pathname onto the history stack. Called by the
   *  NavigationHistoryTracker when the user navigates forward. */
  pushHistory: (pathname: string) => void;
  /** Pop the top of the history stack. Called by the
   *  NavigationHistoryTracker when the user navigates back to the page
   *  that was previously on top of the stack. */
  popHistory: () => void;
}

export const useBreadcrumbStore = create<BreadcrumbStore>((set) => ({
  hints: {},
  historyStack: [],
  labelCache: {},
  setHint: (pathname, hint) =>
    set((state) => ({
      hints: { ...state.hints, [pathname]: hint },
    })),
  clearHint: (pathname) =>
    set((state) => {
      const next = { ...state.hints };
      delete next[pathname];
      return { hints: next };
    }),
  cacheLabel: (pathname, label) =>
    set((state) => {
      // Skip the no-op write so subscribers don't re-render when the
      // hint re-fires with the same label (common during query refetches).
      if (state.labelCache[pathname] === label) return state;
      return { labelCache: { ...state.labelCache, [pathname]: label } };
    }),
  pushHistory: (pathname) =>
    set((state) => {
      const next = [...state.historyStack, pathname];
      if (next.length > HISTORY_LIMIT) next.shift();
      return { historyStack: next };
    }),
  popHistory: () => set((state) => ({ historyStack: state.historyStack.slice(0, -1) })),
}));
