import type { TaskItem } from "./contracts.ts";

export type NumberedTaskItem = TaskItem & { outlineRef: string };

export function numberTaskTree(tasks: TaskItem[]): NumberedTaskItem[] {
  const ordered = [...tasks].sort((left, right) => left.sortOrder - right.sortOrder || left.createdAt.localeCompare(right.createdAt) || left.id.localeCompare(right.id));
  const taskIds = new Set(ordered.map((task) => task.id));
  const children = new Map<string | null, TaskItem[]>();
  for (const task of ordered) {
    const parentId = task.parentId !== null && taskIds.has(task.parentId) ? task.parentId : null;
    children.set(parentId, [...(children.get(parentId) ?? []), task]);
  }

  const refs = new Map<string, string>();
  const visit = (parentId: string | null, prefix: string) => {
    for (const [index, task] of (children.get(parentId) ?? []).entries()) {
      if (refs.has(task.id)) continue;
      const outlineRef = prefix ? `${prefix}.${index + 1}` : `R${index + 1}`;
      refs.set(task.id, outlineRef);
      visit(task.id, outlineRef);
    }
  };
  visit(null, "");

  return ordered.map((task, index) => ({ ...task, outlineRef: refs.get(task.id) ?? `R${index + 1}` }));
}
