import { __toESM } from "../../../../../_virtual/rolldown_runtime.js";
import { __name, log } from "./chunk-AGHRB4JF.js";
import select_default from "../../../../d3-selection/src/select.js";
import "../../../../d3/src/index.js";
import { cytoscape } from "../../../../cytoscape/dist/cytoscape.esm.js";
import { require_cytoscape_cose_bilkent } from "../../../../cytoscape-cose-bilkent/cytoscape-cose-bilkent.js";
var import_cytoscape_cose_bilkent = /* @__PURE__ */ __toESM(require_cytoscape_cose_bilkent(), 1);
cytoscape.use(import_cytoscape_cose_bilkent.default);
function addNodes(e, n) {
	e.forEach((e) => {
		let r = {
			id: e.id,
			labelText: e.label,
			height: e.height,
			width: e.width,
			padding: e.padding ?? 0
		};
		Object.keys(e).forEach((n) => {
			[
				"id",
				"label",
				"height",
				"width",
				"padding",
				"x",
				"y"
			].includes(n) || (r[n] = e[n]);
		}), n.add({
			group: "nodes",
			data: r,
			position: {
				x: e.x ?? 0,
				y: e.y ?? 0
			}
		});
	});
}
__name(addNodes, "addNodes");
function addEdges(e, n) {
	e.forEach((e) => {
		let r = {
			id: e.id,
			source: e.start,
			target: e.end
		};
		Object.keys(e).forEach((n) => {
			[
				"id",
				"start",
				"end"
			].includes(n) || (r[n] = e[n]);
		}), n.add({
			group: "edges",
			data: r
		});
	});
}
__name(addEdges, "addEdges");
function createCytoscapeInstance(e) {
	return new Promise((n) => {
		let o = select_default("body").append("div").attr("id", "cy").attr("style", "display:none"), s = cytoscape({
			container: document.getElementById("cy"),
			style: [{
				selector: "edge",
				style: { "curve-style": "bezier" }
			}]
		});
		o.remove(), addNodes(e.nodes, s), addEdges(e.edges, s), s.nodes().forEach(function(e) {
			e.layoutDimensions = () => {
				let n = e.data();
				return {
					w: n.width,
					h: n.height
				};
			};
		}), s.layout({
			name: "cose-bilkent",
			quality: "proof",
			styleEnabled: !1,
			animate: !1
		}).run(), s.ready((e) => {
			log.info("Cytoscape ready", e), n(s);
		});
	});
}
__name(createCytoscapeInstance, "createCytoscapeInstance");
function extractPositionedNodes(e) {
	return e.nodes().map((e) => {
		let n = e.data(), r = e.position(), i = {
			id: n.id,
			x: r.x,
			y: r.y
		};
		return Object.keys(n).forEach((e) => {
			e !== "id" && (i[e] = n[e]);
		}), i;
	});
}
__name(extractPositionedNodes, "extractPositionedNodes");
function extractPositionedEdges(e) {
	return e.edges().map((e) => {
		let n = e.data(), r = e._private.rscratch, i = {
			id: n.id,
			source: n.source,
			target: n.target,
			startX: r.startX,
			startY: r.startY,
			midX: r.midX,
			midY: r.midY,
			endX: r.endX,
			endY: r.endY
		};
		return Object.keys(n).forEach((e) => {
			[
				"id",
				"source",
				"target"
			].includes(e) || (i[e] = n[e]);
		}), i;
	});
}
__name(extractPositionedEdges, "extractPositionedEdges");
async function executeCoseBilkentLayout(e, n) {
	log.debug("Starting cose-bilkent layout algorithm");
	try {
		validateLayoutData(e);
		let n = await createCytoscapeInstance(e), i = extractPositionedNodes(n), a = extractPositionedEdges(n);
		return log.debug(`Layout completed: ${i.length} nodes, ${a.length} edges`), {
			nodes: i,
			edges: a
		};
	} catch (e) {
		throw log.error("Error in cose-bilkent layout algorithm:", e), e;
	}
}
__name(executeCoseBilkentLayout, "executeCoseBilkentLayout");
function validateLayoutData(e) {
	if (!e) throw Error("Layout data is required");
	if (!e.config) throw Error("Configuration is required in layout data");
	if (!e.rootNode) throw Error("Root node is required");
	if (!e.nodes || !Array.isArray(e.nodes)) throw Error("No nodes found in layout data");
	if (!Array.isArray(e.edges)) throw Error("Edges array is required in layout data");
	return !0;
}
__name(validateLayoutData, "validateLayoutData");
var render2 = /* @__PURE__ */ __name(async (e, n, { insertCluster: r, insertEdge: i, insertEdgeLabel: a, insertMarkers: o, insertNode: s, log: c, positionEdgeLabel: l }, { algorithm: u }) => {
	let d = {}, f = {}, p = n.select("g");
	o(p, e.markers, e.type, e.diagramId);
	let m = p.insert("g").attr("class", "subgraphs"), h = p.insert("g").attr("class", "edgePaths"), g = p.insert("g").attr("class", "edgeLabels"), _ = p.insert("g").attr("class", "nodes");
	c.debug("Inserting nodes into DOM for dimension calculation"), await Promise.all(e.nodes.map(async (n) => {
		if (n.isGroup) {
			let e = { ...n };
			f[n.id] = e, d[n.id] = e, await r(m, n);
		} else {
			let r = { ...n };
			d[n.id] = r;
			let i = await s(_, n, {
				config: e.config,
				dir: e.direction || "TB"
			}), a = i.node().getBBox();
			r.width = a.width, r.height = a.height, r.domId = i, c.debug(`Node ${n.id} dimensions: ${a.width}x${a.height}`);
		}
	})), c.debug("Running cose-bilkent layout algorithm");
	let v = await executeCoseBilkentLayout({
		...e,
		nodes: e.nodes.map((e) => {
			let n = d[e.id];
			return {
				...e,
				width: n.width,
				height: n.height
			};
		})
	}, e.config);
	c.debug("Positioning nodes based on layout results"), v.nodes.forEach((e) => {
		let n = d[e.id];
		n?.domId && (n.domId.attr("transform", `translate(${e.x}, ${e.y})`), n.x = e.x, n.y = e.y, c.debug(`Positioned node ${n.id} at center (${e.x}, ${e.y})`));
	}), v.edges.forEach((n) => {
		let r = e.edges.find((e) => e.id === n.id);
		r && (r.points = [
			{
				x: n.startX,
				y: n.startY
			},
			{
				x: n.midX,
				y: n.midY
			},
			{
				x: n.endX,
				y: n.endY
			}
		]);
	}), c.debug("Inserting and positioning edges"), await Promise.all(e.edges.map(async (n) => {
		await a(g, n);
		let r = d[n.start ?? ""], o = d[n.end ?? ""];
		if (r && o) {
			let a = v.edges.find((e) => e.id === n.id);
			if (a) {
				c.debug("APA01 positionedEdge", a);
				let s = { ...n };
				l(s, i(h, s, f, e.type, r, o, e.diagramId));
			} else {
				let a = {
					...n,
					points: [{
						x: r.x || 0,
						y: r.y || 0
					}, {
						x: o.x || 0,
						y: o.y || 0
					}]
				};
				l(a, i(h, a, f, e.type, r, o, e.diagramId));
			}
		}
	})), c.debug("Cose-bilkent rendering completed");
}, "render");
export { render2 as render };
