/**
 * What Piggy is looking at.
 *
 * This type crosses four process boundaries — the browser, the API relay, the
 * Piggy chat server and the model prompt — and both server-side zod schemas
 * are `.strict()`. Widening it in one place and not the others does not fail
 * loudly; it produces a 400 `invalid_request` at whichever hop was missed. So
 * the shape lives here, once, and every hop derives from it.
 *
 * Two kinds of context, deliberately distinguished:
 *
 *   record — the user opened Piggy from a specific row. Piggy gets a tool that
 *            reads exactly that record and cannot pivot to another, which is
 *            why the tool's input schema is empty rather than taking an id.
 *   page   — Piggy is docked and the user is simply on a page. There is no id.
 *            The route is what Piggy knows, and it selects which read tool it
 *            is given.
 *
 * `route` is a closed set rather than free text. A docked panel publishes the
 * route on every navigation, so free text would put arbitrary client-supplied
 * strings into a model prompt on every page change.
 */

/** Record types Piggy can be pointed at. Each maps to a `pig_get_record` read. */
export const PIGGY_RECORD_TYPES = [
  'account',
  'contact',
  'demand_deal',
  'supply_deal',
  'contract',
  'commitment',
] as const;

export type PiggyRecordType = (typeof PIGGY_RECORD_TYPES)[number];

/**
 * Routes the dock may report. Kept in step with the NAV table in Shell.tsx.
 * A route absent from this list is reported as `/` rather than rejected —
 * a new page should never break the dock.
 */
export const PIGGY_PAGE_ROUTES = [
  '/',
  '/growth',
  '/margin',
  '/calendar',
  '/capacity',
  '/demand',
  '/supply',
  '/accounts',
  '/contracts',
  '/imports',
  '/team',
  '/facts',
  '/learn',
  // Order is load-bearing for the first time in this list. `toPiggyPageRoute`
  // takes the FIRST match and matches on prefix, so '/motion' listed above its
  // children would swallow '/motion/library/:id' and report the whole feature
  // as one page. Most specific first.
  '/motion/library',
  '/motion/engagements',
  '/motion',
  '/settings',
  '/piggy',
] as const;

export type PiggyPageRoute = (typeof PIGGY_PAGE_ROUTES)[number];

export type PiggyChatContext =
  | { type: PiggyRecordType; id: string; label?: string }
  | { type: 'page'; route: PiggyPageRoute; label?: string };

/** Narrowing helper, so callers do not re-derive the discriminant test. */
export function isPageContext(
  context: PiggyChatContext | undefined,
): context is Extract<PiggyChatContext, { type: 'page' }> {
  return context?.type === 'page';
}

/**
 * Coerce an arbitrary router pathname to a route the dock may publish.
 *
 * Falls back to '/' rather than throwing: an unknown route means a page was
 * added without updating this list, and the correct behaviour there is a
 * slightly less specific Piggy, not a broken one.
 */
export function toPiggyPageRoute(pathname: string): PiggyPageRoute {
  const match = PIGGY_PAGE_ROUTES.find(
    (route) => route === pathname || (route !== '/' && pathname.startsWith(`${route}/`)),
  );
  return match ?? '/';
}
