/* Parley — the route table.

   Deliberately NOT routes: the ⌘K palette, the composer and its model picker,
   the attachment tray, the context rail, the share menu, the rename and delete
   dialogs, and the streaming turn. They are states of a screen. A breadcrumb
   that wants one of them is a bug in the screen, and no route is ever added to
   make a link resolve.

   Six top-level destinations, and this product runs the SIDEBAR shell for a
   reason the count would not settle on its own: the thread list. Chats'
   within-destination level is the recent conversations, which have to stay one
   click away while you read one of them; a top bar cannot own that, and putting
   it on the page would mean the reading column shares its width with a list.
   So: sidebar shell, destinations in the upper groups, threads nested under
   Chats as its children (AGENTS §6.3), and no tabs on the thread screen.

   /chats/archived sits under Chats rather than beside it: the archive is a
   shelf of the same destination, reached from the foot of the nested list. */

const PARLEY_NAV = [
  { path: "/", label: "Chats", icon: "message-square", group: "Work" },
  { path: "/shared", label: "Shared with me", icon: "users", group: "Work" },
  { path: "/projects", label: "Projects", icon: "folder-open", group: "Work" },
  { path: "/library", label: "Library", icon: "bookmark", group: "Work" },
  { path: "/files", label: "Files", icon: "paperclip", group: "Workspace", badge: "filesNeedingAttention" },
  { path: "/usage", label: "Usage", icon: "gauge", group: "Workspace" },

  /* Registered, not in the nav. */
  { path: "/chats/:id", label: "Thread", parent: "/", offSidebar: true },
  { path: "/chats/archived", label: "Archived chats", parent: "/", offSidebar: true, group: "Shelves" },
  { path: "/search", label: "Search results", offSidebar: true, group: "Shelves" },
  { path: "/projects/:id", label: "Project", parent: "/projects", offSidebar: true },
  { path: "/library/:id", label: "Prompt", parent: "/library", offSidebar: true },
  { path: "/files/:id", label: "File", parent: "/files", offSidebar: true },
  { path: "/settings/account", label: "Account", offSidebar: true },
  { path: "/settings/models", label: "Models and defaults", offSidebar: true },
  { path: "/settings/workspace", label: "Workspace", offSidebar: true },
  { path: "/settings/billing", label: "Plan and billing", offSidebar: true },

  /* Auth namespace — excluded from the nav; renders no product chrome. */
  { path: "/signin", label: "Sign in", offSidebar: true },
  { path: "/signup", label: "Create account", offSidebar: true },
  { path: "/forgot-password", label: "Reset password", offSidebar: true },
  { path: "/check-email", label: "Check your email", offSidebar: true },
  { path: "/signout", label: "Sign out", offSidebar: true },
];

const PARLEY_ROUTES = indexRoutes(PARLEY_NAV);

/* The projections the shell renders — derived by filtering the tree, never
   retyped. Two groups, so both carry a label (AGENTS §6.3). */
const PARLEY_SIDEBAR = ["Work", "Workspace"].map((label) => ({
  label: label,
  items: PARLEY_NAV.filter((r) => !r.offSidebar && r.group === label),
}));

const PARLEY_ACCOUNT_MENU = [
  PARLEY_ROUTES["/settings/account"],
  PARLEY_ROUTES["/settings/models"],
  PARLEY_ROUTES["/settings/workspace"],
  PARLEY_ROUTES["/settings/billing"],
  PARLEY_ROUTES["/signout"],
];

/* One badge in the whole sidebar, and it counts one predicate over one array:
   files the index could not read. The Files table's warning row count and the
   project record's "needs you" line call the same function.
   Shared with me deliberately carries none: nothing here records what you have
   already read, so a count would be counting threads, not news. */
const NAV_BADGES = {
  filesNeedingAttention: {
    label: "files the index could not read",
    count: (data) => data.files.filter(FILE_FLAGS.needsAttention).length,
  },
};

/* Paths that render without product chrome (AGENTS §7.1). */
const PARLEY_AUTH_PATHS = ["/signin", "/signup", "/forgot-password", "/check-email", "/signout"];

/* /chats/:id → /chats/t_lifecycle. Breadcrumbs and nested nav rows use it, so
   no screen builds a path by concatenation. */
function resolvePath(pattern, params) {
  return pattern.replace(/:([^/]+)/g, (_, key) => (params && params[key] != null ? params[key] : ":" + key));
}

/* The preview menu's page list — this table read whole and grouped, never
   retyped, with the parameterised routes resolved against the fixture so the
   link lands on a real record rather than on ":id". A pattern with no fixture
   example is left out rather than offered as a link resolving nowhere. */
const PARLEY_PAGES = (data) => {
  const thread = data.threads[0], project = data.projects[0], prompt = data.prompts[0], file = data.files[0];
  return templatePages(PARLEY_NAV, PARLEY_AUTH_PATHS, {
    "/chats/:id": thread ? resolvePath("/chats/:id", { id: thread.id }) : null,
    "/projects/:id": project ? resolvePath("/projects/:id", { id: project.id }) : null,
    "/library/:id": prompt ? resolvePath("/library/:id", { id: prompt.id }) : null,
    "/files/:id": file ? resolvePath("/files/:id", { id: file.id }) : null,
  });
};

Object.assign(window, { PARLEY_NAV, PARLEY_ROUTES, PARLEY_SIDEBAR, PARLEY_ACCOUNT_MENU, NAV_BADGES, PARLEY_AUTH_PATHS, PARLEY_PAGES, resolvePath });
