import {
  ORGANIGRAMA_CARD_WIDTH_PX,
  ORGANIGRAMA_CARD_MIN_HEIGHT_PX,
  ORGANIGRAMA_NODE_H_GAP_PX,
  ORGANIGRAMA_NODE_V_GAP_PX,
} from './organigramaStyles';

/**
 * Layout horizontal de árbol: devuelve posiciones de nodos y aristas SVG.
 * @param {object} root
 * @returns {{ nodes: Array<{ unit, x, y }>, edges: Array<{ fromId, toId, path }>, width, height }}
 */
export function layoutOrganigramaTree(root) {
  if (!root) return { nodes: [], edges: [], width: 0, height: 0 };

  const unitSlot = ORGANIGRAMA_CARD_WIDTH_PX + ORGANIGRAMA_NODE_H_GAP_PX;
  const positions = new Map();
  const edges = [];

  function layout(node, depth, leafStart) {
    const children = node?.children ?? [];
    if (children.length === 0) {
      const x = leafStart * unitSlot;
      const y = depth * (ORGANIGRAMA_CARD_MIN_HEIGHT_PX + ORGANIGRAMA_NODE_V_GAP_PX);
      positions.set(node.id, { unit: node, x, y });
      return { leafStart: leafStart + 1, x, y };
    }

    let cursor = leafStart;
    const childCenters = [];
    for (const child of children) {
      const result = layout(child, depth + 1, cursor);
      cursor = result.leafStart;
      childCenters.push({
        id: child.id,
        x: result.x + ORGANIGRAMA_CARD_WIDTH_PX / 2,
        y: result.y,
      });
      edges.push({ fromId: node.id, toId: child.id });
    }

    const firstCenter = childCenters[0].x;
    const lastCenter = childCenters[childCenters.length - 1].x;
    const x = (firstCenter + lastCenter) / 2 - ORGANIGRAMA_CARD_WIDTH_PX / 2;
    const y = depth * (ORGANIGRAMA_CARD_MIN_HEIGHT_PX + ORGANIGRAMA_NODE_V_GAP_PX);
    positions.set(node.id, { unit: node, x, y });

    return { leafStart: cursor, x, y };
  }

  layout(root, 0, 0);

  const nodes = Array.from(positions.values());
  const maxX = Math.max(...nodes.map((n) => n.x), 0) + ORGANIGRAMA_CARD_WIDTH_PX;
  const maxY = Math.max(...nodes.map((n) => n.y), 0) + ORGANIGRAMA_CARD_MIN_HEIGHT_PX;

  const edgePaths = edges.map(({ fromId, toId }) => {
    const from = positions.get(fromId);
    const to = positions.get(toId);
    if (!from || !to) return null;
    const x1 = from.x + ORGANIGRAMA_CARD_WIDTH_PX / 2;
    const y1 = from.y + ORGANIGRAMA_CARD_MIN_HEIGHT_PX;
    const x2 = to.x + ORGANIGRAMA_CARD_WIDTH_PX / 2;
    const y2 = to.y;
    const midY = (y1 + y2) / 2;
    const path = `M ${x1} ${y1} C ${x1} ${midY}, ${x2} ${midY}, ${x2} ${y2}`;
    return { fromId, toId, path };
  }).filter(Boolean);

  return {
    nodes,
    edges: edgePaths,
    width: maxX + ORGANIGRAMA_NODE_H_GAP_PX,
    height: maxY + ORGANIGRAMA_NODE_V_GAP_PX,
  };
}
