/* Ward Desk — the route table.
   Deliberately NOT routes: the ⌘K palette, the notifications panel, the rail's
   category flyout, every row menu, every filter bar, the import wizard dialog,
   the bed-assignment dialog and every confirm dialog. They are states of a
   screen. A breadcrumb that wants one of them is a bug in the screen, not a
   missing route.

   Twenty top-level destinations over six categories, dense record work and ten
   per-destination counts, so this product runs the SIDEBAR shell in its
   RAIL + PANEL mode: the rail owns the category, the panel owns the destinations
   inside it. The category is not a route — it is the sectioning device, so a
   category holds 2–4 destinations rather than §6.3's 5–9 for a labelled group,
   and the panel header names it instead of an uppercase group label.

   Parameterised routes exist where the thing has its own controls and its own
   numbers: a patient (their admission, chart, procedures and the notes written
   on them), a procedure (its theatre slot, consent and team), a member of staff
   (what they are responsible for and what they have written). Registering a new
   patient is a route rather than a dialog because it is a real form.

   Settings is two screens off the sidebar, reached from the account menu. The
   auth namespace carries sign-in and the whole password reset flow; signup, MFA
   and lockout are not built, so nothing links to them. */

const HD_CATEGORIES = [
  { id: "care", label: "Care", note: "Wards, patients and theatre", icon: "stethoscope" },
  { id: "pharmacy", label: "Pharmacy", note: "Prescribing and stock", icon: "pill" },
  { id: "people", label: "People", note: "Who is on the badge system", icon: "users-round" },
  { id: "finance", label: "Finance", note: "What care cost and who owes it", icon: "landmark" },
  { id: "business", label: "Business", note: "Contracts, debt and what care costs", icon: "briefcase" },
  { id: "workspace", label: "Workspace", note: "The hospital's own record", icon: "message-circle" },
];

const HD_NAV = [
  /* Care */
  { path: "/", label: "Today", icon: "layout-dashboard", category: "care" },
  { path: "/patients", label: "Patients", icon: "contact-round", category: "care" },
  { path: "/admissions", label: "Admissions", icon: "bed", badge: "bedsWaiting", category: "care" },
  { path: "/interventions", label: "Interventions", icon: "scissors", badge: "consentMissing", category: "care" },
  { path: "/wards", label: "Wards and beds", icon: "layout-grid", category: "care" },

  /* Pharmacy */
  { path: "/medication", label: "Medication orders", icon: "pill", badge: "ordersAwaitingPharmacy", category: "pharmacy" },
  { path: "/rounds", label: "Drug round", icon: "clipboard-check", badge: "dosesDueOrMissed", category: "pharmacy" },
  { path: "/formulary", label: "Formulary and stock", icon: "package", category: "pharmacy" },

  /* Finance */
  { path: "/invoices", label: "Invoices", icon: "file-text", badge: "invoicesToCode", category: "finance" },
  { path: "/payments", label: "Payments", icon: "banknote", category: "finance" },
  { path: "/revenue", label: "Revenue and debt", icon: "chart-line", category: "finance" },

  /* Business */
  { path: "/contracts", label: "Contracts and tariffs", icon: "file-signature", badge: "linesOffContract", category: "business" },
  { path: "/credit-control", label: "Credit control", icon: "phone-call", badge: "invoicesOverdue", category: "business" },
  { path: "/margin", label: "Cost and margin", icon: "scale", badge: "thinMargins", category: "business" },

  /* People */
  { path: "/doctors", label: "Doctors", icon: "stethoscope", category: "people" },
  { path: "/employees", label: "Employees", icon: "id-card", category: "people" },
  { path: "/rota", label: "Rota", icon: "calendar-days", badge: "shiftsUnderstaffed", category: "people" },

  /* Workspace */
  { path: "/feed", label: "Feed", icon: "message-circle", badge: "mentionsOwed", category: "workspace" },
  { path: "/reports", label: "Reports", icon: "chart-line", category: "workspace" },
  { path: "/data", label: "Import and export", icon: "arrow-down-up", badge: "transfersNeedingReview", category: "workspace" },

  /* Registered, not in the nav. */
  { path: "/patients/new", label: "New patient", parent: "/patients", offSidebar: true },
  { path: "/patients/:id", label: "Patient", parent: "/patients", offSidebar: true },
  { path: "/interventions/:id", label: "Intervention", parent: "/interventions", offSidebar: true },
  { path: "/invoices/:id", label: "Invoice", parent: "/invoices", offSidebar: true },
  { path: "/doctors/:id", label: "Doctor", parent: "/doctors", offSidebar: true },
  { path: "/employees/:id", label: "Employee", parent: "/employees", offSidebar: true },
  { path: "/me/profile", label: "Your profile", offSidebar: true },

  /* Settings: one namespace, seven registered screens. They are off the sidebar
     and reached from the account menu; the within-destination level is a tab
     strip on the page, derived from this table (§5, §6.3) — never a third
     navigation column. */
  { path: "/settings", label: "Hospital", offSidebar: true, group: "Settings" },
  { path: "/settings/wards", label: "Wards and beds", parent: "/settings", offSidebar: true, group: "Settings" },
  { path: "/settings/roles", label: "Roles and permissions", parent: "/settings", offSidebar: true, group: "Settings" },
  { path: "/settings/billing", label: "Billing", parent: "/settings", offSidebar: true, group: "Settings" },
  { path: "/settings/integrations", label: "Integrations and feeds", parent: "/settings", offSidebar: true, group: "Settings" },
  { path: "/settings/notifications", label: "Notifications", parent: "/settings", offSidebar: true, group: "Settings" },
  { path: "/settings/security", label: "Security", parent: "/settings", offSidebar: true, group: "Settings" },

  /* Auth namespace — excluded from the shell nav; no product chrome. The reset
     flow is all four screens AGENTS §7.5 requires, plus the expired-token state:
     request, the sent confirmation, set-new behind the token, the outcome and the
     dead link. Signup, MFA and lockout are not built, so nothing links to them. */
  { path: "/signin", label: "Sign in", offSidebar: true },
  { path: "/forgot-password", label: "Forgot password", offSidebar: true },
  { path: "/forgot-password/sent", label: "Reset link sent", parent: "/forgot-password", offSidebar: true },
  { path: "/reset-password", label: "Set a new password", offSidebar: true },
  { path: "/reset-password/expired", label: "Reset link expired", parent: "/reset-password", offSidebar: true },
  { path: "/reset-password/done", label: "Password changed", parent: "/reset-password", offSidebar: true },
];

const HD_ROUTES = indexRoutes(HD_NAV);

/* Projections the shell renders — derived by filtering the tree, never retyped. */
const HD_RAIL = HD_CATEGORIES.map((category) => Object.assign({}, category, {
  items: HD_NAV.filter((r) => !r.offSidebar && r.category === category.id),
}));

/* Which category a path belongs to — the rail's active state is derived from the
   route, exactly like the panel's. Settings, your profile and auth belong to no
   category, so this returns null and the shell keeps whichever category the
   reader was already in rather than snapping them back to the first one. */
function categoryOf(path) {
  const route = matchRoute(path, HD_ROUTES);
  if (!route) return null;
  if (route.category) return route.category;
  let node = route;
  while (node && node.parent && HD_ROUTES[node.parent]) {
    node = HD_ROUTES[node.parent];
    if (node.category) return node.category;
  }
  return null;
}

/* The settings tab strip — the route table filtered, never retyped. */
const HD_SETTINGS_NAV = HD_NAV.filter((r) => r.group === "Settings");

/* The account menu carries registered routes plus sign out (§6.2). Settings is
   one entry: its own tab strip carries the seven screens inside it. */
const HD_ACCOUNT_MENU = [HD_ROUTES["/me/profile"], HD_ROUTES["/settings"]];

/* Paths that render without product chrome (AGENTS §7.1). */
const HD_AUTH_PATHS = ["/signin", "/forgot-password", "/forgot-password/sent", "/reset-password", "/reset-password/expired", "/reset-password/done"];

/* /patients/:id → /patients/pat_04. Breadcrumbs and every nested row use it, so
   no screen builds a path by concatenation. */
const resolvePath = (pattern, params) => pattern.replace(/:([^/]+)/g, (_, key) => (params && params[key] != null ? params[key] : ":" + key));

/* The preview menu's page list — this table read whole and grouped, with the
   parameterised routes resolved against the fixture so each link lands on a real
   record rather than on ":id". */
const HD_PAGES = (data) => {
  const patient = data.patients[0];
  const intervention = data.interventions[0];
  const invoice = data.invoices[0];
  const doctor = data.staff.find((s) => s.family === "medical");
  const employee = data.staff.find((s) => s.family !== "medical");
  return templatePages(HD_NAV, HD_AUTH_PATHS, {
    "/patients/:id": patient ? resolvePath("/patients/:id", { id: patient.id }) : null,
    "/interventions/:id": intervention ? resolvePath("/interventions/:id", { id: intervention.id }) : null,
    "/invoices/:id": invoice ? resolvePath("/invoices/:id", { id: invoice.id }) : null,
    "/doctors/:id": doctor ? resolvePath("/doctors/:id", { id: doctor.id }) : null,
    "/employees/:id": employee ? resolvePath("/employees/:id", { id: employee.id }) : null,
  });
};

Object.assign(window, { HD_CATEGORIES, HD_NAV, HD_ROUTES, HD_RAIL, HD_SETTINGS_NAV, HD_ACCOUNT_MENU, HD_AUTH_PATHS, HD_PAGES, categoryOf, resolvePath });
