export function findNodeByRelativePath(nodes, relativePath, rootId) {
  const targetId = `${rootId}${relativePath}`;

  function walk(node) {
    if (node.id === targetId) return node;
    if (node.children) {
      for (const child of node.children) {
        const found = walk(child);
        if (found) return found;
      }
    }
    return null;
  }

  for (const node of nodes) {
    const found = walk(node);
    if (found) return found;
  }
  return null;
}

/** Expand ancestor folders so the given node ids are visible. */
export function expandPathsToReveal(nodes, targetIds) {
  const idSet = new Set(targetIds);

  function walk(node) {
    if (!node.children?.length) return idSet.has(node.id);

    let childVisible = false;
    for (const child of node.children) {
      if (walk(child)) childVisible = true;
    }

    if (childVisible && node.type === 'folder') {
      node.expanded = true;
    }

    return childVisible || idSet.has(node.id);
  }

  nodes.forEach(walk);
}

export function nodeIdsForRelativePaths(nodes, rootId, relativePaths) {
  return relativePaths
    .map((path) => {
      const node = findNodeByRelativePath(nodes, path, rootId);
      return node?.id ?? null;
    })
    .filter(Boolean);
}

export function findNodeById(nodes, id) {
  for (const node of nodes ?? []) {
    if (node.id === id) return node;
    const hit = findNodeById(node.children, id);
    if (hit) return hit;
  }
  return null;
}
