import type { EDMFolder } from "./types";

/**
 * Flatten the folder tree into Mantine Select options.
 *
 * Folders arrive from the API as a flat list with parent_id, and Mantine's
 * Select takes no nesting, so depth is conveyed by prefixing the label.
 *
 * Built by walking down from the roots rather than by sorting a flat list —
 * that is what guarantees a child never appears above its own parent.
 */
export const folderSelectOptions = (
  folders: EDMFolder[],
): { value: string; label: string }[] => {
  const ids = new Set(folders.map((f) => f.id));
  const byParent = new Map<string | null, EDMFolder[]>();

  // A folder pointing at a missing parent would otherwise never be reached by
  // the walk and would vanish from every picker, leaving no way to re-file it.
  // ON DELETE SET NULL should prevent this, but a manual DB edit could not.
  const orphans: EDMFolder[] = [];

  for (const f of folders) {
    const parent = f.parent_id ?? null;
    if (parent !== null && !ids.has(parent)) {
      orphans.push(f);
      continue;
    }
    byParent.set(parent, [...(byParent.get(parent) ?? []), f]);
  }

  const out: { value: string; label: string }[] = [];

  const walk = (parent: string | null, depth: number) => {
    const children = (byParent.get(parent) ?? []).sort(
      (a, b) => a.sort_order - b.sort_order || a.name.localeCompare(b.name),
    );
    for (const f of children) {
      out.push({ value: f.id, label: `${"— ".repeat(depth)}${f.name}` });
      walk(f.id, depth + 1);
    }
  };
  walk(null, 0);

  for (const o of orphans) {
    out.push({ value: o.id, label: `${o.name} (detached)` });
  }

  return out;
};
