/* Halo layer — soft rounded blob behind each parent + its descendant cluster.
   Renders as SVG so it sits below nodes but above the canvas background. */

function computeClusters(nodes, childrenMap, hiddenNodes) {
  // For every node that has children, build a cluster = itself + all visible descendants.
  const clusters = [];
  Object.values(nodes).forEach(n => {
    if (hiddenNodes.has(n.id)) return;
    const kids = childrenMap[n.id] || [];
    if (!kids.length) return;
    const members = [n.id];
    const visited = new Set([n.id]);
    const stack = [...kids];
    while (stack.length) {
      const id = stack.pop();
      if (visited.has(id)) continue;
      if (hiddenNodes.has(id)) continue;
      visited.add(id);
      members.push(id);
      (childrenMap[id] || []).forEach(c => stack.push(c));
    }
    if (members.length < 2) return;
    // Bounding box
    const pts = members.map(id => nodes[id]).filter(Boolean);
    if (!pts.length) return;
    const xs = pts.map(p => p.x), ys = pts.map(p => p.y);
    const minX = Math.min(...xs), maxX = Math.max(...xs);
    const minY = Math.min(...ys), maxY = Math.max(...ys);
    const PAD = 56;
    clusters.push({
      id: n.id,
      depth: pts.length, // bigger clusters drawn first (behind)
      x: minX - PAD,
      y: minY - PAD,
      w: (maxX - minX) + PAD * 2,
      h: (maxY - minY) + PAD * 2,
    });
  });
  // Draw larger clusters first so nested smaller clusters layer on top
  clusters.sort((a, b) => b.depth - a.depth);
  return clusters;
}

function HaloLayer({ nodes, childrenMap, hiddenNodes }) {
  const clusters = computeClusters(nodes, childrenMap, hiddenNodes);
  return (
    <svg className="halos" aria-hidden="true">
      {clusters.map(c => (
        <rect key={c.id}
          x={c.x} y={c.y} width={c.w} height={c.h}
          rx="42" ry="42"
          className="halo-rect"
        />
      ))}
    </svg>
  );
}

window.HaloLayer = HaloLayer;
window.computeClusters = computeClusters;
