import { __name, log } from "./chunk-AGHRB4JF.js";
import { getConfig2 } from "./chunk-ABZYJK2D.js";
import "./chunk-HN2XXSSU.js";
import { getSubGraphTitleMargins } from "./chunk-CVBHYZKI.js";
import "./chunk-ATLVNIR6.js";
import "./chunk-S3R3BYOJ.js";
import "./chunk-JA3XYJ7Z.js";
import { clear as clear$1, clear2, insertCluster, insertNode, positionNode, setNodeElem, updateNodeBounds } from "./chunk-JZLCHNYA.js";
import { clear, insertEdge, insertEdgeLabel, markers_default, positionEdgeLabel } from "./chunk-QXUST7PY.js";
import { Graph } from "../../../../dagre-d3-es/src/graphlib/graph.js";
import "../../../../dagre-d3-es/src/graphlib/index.js";
import { layout } from "../../../../dagre-d3-es/src/dagre/layout.js";
import "../../../../dagre-d3-es/src/dagre/index.js";
import { write } from "../../../../dagre-d3-es/src/graphlib/json.js";
var clusterDb = /* @__PURE__ */ new Map(), descendants = /* @__PURE__ */ new Map(), parents = /* @__PURE__ */ new Map(), clear4 = /* @__PURE__ */ __name(() => {
	descendants.clear(), parents.clear(), clusterDb.clear();
}, "clear"), isDescendant = /* @__PURE__ */ __name((e, v) => {
	let y = descendants.get(v) || [];
	return log.trace("In isDescendant", v, " ", e, " = ", y.includes(e)), y.includes(e);
}, "isDescendant"), edgeInCluster = /* @__PURE__ */ __name((e, v) => {
	let y = descendants.get(v) || [];
	return log.info("Descendants of ", v, " is ", y), log.info("Edge is ", e), e.v === v || e.w === v ? !1 : y ? y.includes(e.v) || isDescendant(e.v, v) || isDescendant(e.w, v) || y.includes(e.w) : (log.debug("Tilt, ", v, ",not in descendants"), !1);
}, "edgeInCluster"), copy = /* @__PURE__ */ __name((e, v, y, b) => {
	log.warn("Copying children of ", e, "root", b, "data", v.node(e), b);
	let x = v.children(e) || [];
	e !== b && x.push(e), log.warn("Copying (nodes) clusterId", e, "nodes", x), x.forEach((x) => {
		if (v.children(x).length > 0) copy(x, v, y, b);
		else {
			let S = v.node(x);
			log.info("cp ", x, " to ", b, " with parent ", e), y.setNode(x, S), b !== v.parent(x) && (log.warn("Setting parent", x, v.parent(x)), y.setParent(x, v.parent(x))), e !== b && x !== e ? (log.debug("Setting parent", x, e), y.setParent(x, e)) : (log.info("In copy ", e, "root", b, "data", v.node(e), b), log.debug("Not Setting parent for node=", x, "cluster!==rootId", e !== b, "node!==clusterId", x !== e));
			let C = v.edges(x);
			log.debug("Copying Edges", C), C.forEach((x) => {
				log.info("Edge", x);
				let S = v.edge(x.v, x.w, x.name);
				log.info("Edge data", S, b);
				try {
					edgeInCluster(x, b) ? (log.info("Copying as ", x.v, x.w, S, x.name), y.setEdge(x.v, x.w, S, x.name), log.info("newGraph edges ", y.edges(), y.edge(y.edges()[0]))) : log.info("Skipping copy of edge ", x.v, "-->", x.w, " rootId: ", b, " clusterId:", e);
				} catch (e) {
					log.error(e);
				}
			});
		}
		log.debug("Removing node", x), v.removeNode(x);
	});
}, "copy"), extractDescendants = /* @__PURE__ */ __name((e, _) => {
	let v = _.children(e), y = [...v];
	for (let b of v) parents.set(b, e), y = [...y, ...extractDescendants(b, _)];
	return y;
}, "extractDescendants"), findCommonEdges = /* @__PURE__ */ __name((e, _, v) => {
	let y = e.edges().filter((e) => e.v === _ || e.w === _), b = e.edges().filter((e) => e.v === v || e.w === v), x = y.map((e) => ({
		v: e.v === _ ? v : e.v,
		w: e.w === _ ? _ : e.w
	})), S = b.map((e) => ({
		v: e.v,
		w: e.w
	}));
	return x.filter((e) => S.some((_) => e.v === _.v && e.w === _.w));
}, "findCommonEdges"), findNonClusterChild = /* @__PURE__ */ __name((e, v, y) => {
	let b = v.children(e);
	if (log.trace("Searching children of id ", e, b), b.length < 1) return e;
	let x;
	for (let e of b) {
		let _ = findNonClusterChild(e, v, y), b = findCommonEdges(v, y, _);
		if (_) if (b.length > 0) x = _;
		else return _;
	}
	return x;
}, "findNonClusterChild"), getAnchorId = /* @__PURE__ */ __name((e) => !clusterDb.has(e) || !clusterDb.get(e).externalConnections ? e : clusterDb.has(e) ? clusterDb.get(e).id : e, "getAnchorId"), adjustClustersAndEdges = /* @__PURE__ */ __name((e, v) => {
	if (!e || v > 10) {
		log.debug("Opting out, no graph ");
		return;
	} else log.debug("Opting in, graph ");
	e.nodes().forEach(function(v) {
		e.children(v).length > 0 && (log.warn("Cluster identified", v, " Replacement id in edges: ", findNonClusterChild(v, e, v)), descendants.set(v, extractDescendants(v, e)), clusterDb.set(v, {
			id: findNonClusterChild(v, e, v),
			clusterData: e.node(v)
		}));
	}), e.nodes().forEach(function(v) {
		let y = e.children(v), b = e.edges();
		y.length > 0 ? (log.debug("Cluster identified", v, descendants), b.forEach((e) => {
			isDescendant(e.v, v) ^ isDescendant(e.w, v) && (log.warn("Edge: ", e, " leaves cluster ", v), log.warn("Descendants of XXX ", v, ": ", descendants.get(v)), clusterDb.get(v).externalConnections = !0);
		})) : log.debug("Not a cluster ", v, descendants);
	});
	for (let _ of clusterDb.keys()) {
		let v = clusterDb.get(_).id, y = e.parent(v);
		y !== _ && clusterDb.has(y) && !clusterDb.get(y).externalConnections && (clusterDb.get(_).id = y);
	}
	e.edges().forEach(function(v) {
		let y = e.edge(v);
		log.warn("Edge " + v.v + " -> " + v.w + ": " + JSON.stringify(v)), log.warn("Edge " + v.v + " -> " + v.w + ": " + JSON.stringify(e.edge(v)));
		let b = v.v, x = v.w;
		if (log.warn("Fix XXX", clusterDb, "ids:", v.v, v.w, "Translating: ", clusterDb.get(v.v), " --- ", clusterDb.get(v.w)), clusterDb.get(v.v) || clusterDb.get(v.w)) {
			if (log.warn("Fixing and trying - removing XXX", v.v, v.w, v.name), b = getAnchorId(v.v), x = getAnchorId(v.w), e.removeEdge(v.v, v.w, v.name), b !== v.v) {
				let _ = e.parent(b);
				clusterDb.get(_).externalConnections = !0, y.fromCluster = v.v;
			}
			if (x !== v.w) {
				let _ = e.parent(x);
				clusterDb.get(_).externalConnections = !0, y.toCluster = v.w;
			}
			log.warn("Fix Replacing with XXX", b, x, v.name), e.setEdge(b, x, y, v.name);
		}
	}), log.warn("Adjusted Graph", write(e)), extractor(e, 0), log.trace(clusterDb);
}, "adjustClustersAndEdges"), extractor = /* @__PURE__ */ __name((e, v) => {
	if (log.warn("extractor - ", v, write(e), e.children("D")), v > 10) {
		log.error("Bailing out");
		return;
	}
	let y = e.nodes(), b = !1;
	for (let _ of y) {
		let v = e.children(_);
		b ||= v.length > 0;
	}
	if (!b) {
		log.debug("Done, no node has children", e.nodes());
		return;
	}
	log.debug("Nodes = ", y, v);
	for (let b of y) if (log.debug("Extracting node", b, clusterDb, clusterDb.has(b) && !clusterDb.get(b).externalConnections, !e.parent(b), e.node(b), e.children("D"), " Depth ", v), !clusterDb.has(b)) log.debug("Not a cluster", b, v);
	else if (!clusterDb.get(b).externalConnections && e.children(b) && e.children(b).length > 0) {
		log.warn("Cluster without external connections, without a parent and with children", b, v);
		let y = e.graph().rankdir === "TB" ? "LR" : "TB";
		clusterDb.get(b)?.clusterData?.dir && (y = clusterDb.get(b).clusterData.dir, log.warn("Fixing dir", clusterDb.get(b).clusterData.dir, y));
		let x = new Graph({
			multigraph: !0,
			compound: !0
		}).setGraph({
			rankdir: y,
			nodesep: 50,
			ranksep: 50,
			marginx: 8,
			marginy: 8
		}).setDefaultEdgeLabel(function() {
			return {};
		});
		log.warn("Old graph before copy", write(e)), copy(b, e, x, b), e.setNode(b, {
			clusterNode: !0,
			id: b,
			clusterData: clusterDb.get(b).clusterData,
			label: clusterDb.get(b).label,
			graph: x
		}), log.warn("New graph after copy node: (", b, ")", write(x)), log.debug("Old graph after copy", write(e));
	} else log.warn("Cluster ** ", b, " **not meeting the criteria !externalConnections:", !clusterDb.get(b).externalConnections, " no parent: ", !e.parent(b), " children ", e.children(b) && e.children(b).length > 0, e.children("D"), v), log.debug(clusterDb);
	y = e.nodes(), log.warn("New list of nodes", y);
	for (let b of y) {
		let y = e.node(b);
		log.warn(" Now next level", b, y), y?.clusterNode && extractor(y.graph, v + 1);
	}
}, "extractor"), sorter = /* @__PURE__ */ __name((e, _) => {
	if (_.length === 0) return [];
	let v = Object.assign([], _);
	return _.forEach((_) => {
		let y = sorter(e, e.children(_));
		v = [...v, ...y];
	}), v;
}, "sorter"), sortNodesByHierarchy = /* @__PURE__ */ __name((e) => sorter(e, e.children()), "sortNodesByHierarchy"), recursiveRender = /* @__PURE__ */ __name(async (v, b, x, T, E, D) => {
	log.warn("Graph in recursive render:XAX", write(b), E);
	let O = b.graph().rankdir;
	log.trace("Dir in recursive render - dir:", O);
	let k = v.insert("g").attr("class", "root");
	b.nodes() ? log.info("Recursive render XXX", b.nodes()) : log.info("No nodes found for", b), b.edges().length > 0 && log.info("Recursive edges", b.edge(b.edges()[0]));
	let A = k.insert("g").attr("class", "clusters"), j = k.insert("g").attr("class", "edgePaths"), M = k.insert("g").attr("class", "edgeLabels"), N = k.insert("g").attr("class", "nodes");
	await Promise.all(b.nodes().map(async function(e) {
		let v = b.node(e);
		if (E !== void 0) {
			let v = JSON.parse(JSON.stringify(E.clusterData));
			log.trace("Setting data for parent cluster XXX\n Node.id = ", e, "\n data=", v.height, "\nParent cluster", E.height), b.setNode(E.id, v), b.parent(e) || (log.trace("Setting parent", e, E.id), b.setParent(e, E.id, v));
		}
		if (log.info("(Insert) Node XXX" + e + ": " + JSON.stringify(b.node(e))), v?.clusterNode) {
			log.info("Cluster identified XBX", e, v.width, b.node(e));
			let { ranksep: y, nodesep: S } = b.graph();
			v.graph.setGraph({
				...v.graph.graph(),
				ranksep: y + 25,
				nodesep: S
			});
			let C = await recursiveRender(N, v.graph, x, T, b.node(e), D), w = C.elem;
			updateNodeBounds(v, w), v.diff = C.diff || 0, log.info("New compound node after recursive render XAX", e, "width", v.width, "height", v.height), setNodeElem(w, v);
		} else b.children(e).length > 0 ? (log.trace("Cluster - the non recursive path XBX", e, v.id, v, v.width, "Graph:", b), log.trace(findNonClusterChild(v.id, b)), clusterDb.set(v.id, {
			id: findNonClusterChild(v.id, b),
			node: v
		})) : (log.trace("Node - the non recursive path XAX", e, N, b.node(e), O), await insertNode(N, b.node(e), {
			config: D,
			dir: O
		}));
	})), await (/* @__PURE__ */ __name(async () => {
		let e = b.edges().map(async function(e) {
			let v = b.edge(e.v, e.w, e.name);
			log.info("Edge " + e.v + " -> " + e.w + ": " + JSON.stringify(e)), log.info("Edge " + e.v + " -> " + e.w + ": ", e, " ", JSON.stringify(b.edge(e))), log.info("Fix", clusterDb, "ids:", e.v, e.w, "Translating: ", clusterDb.get(e.v), clusterDb.get(e.w)), await insertEdgeLabel(M, v);
		});
		await Promise.all(e);
	}, "processEdges"))(), log.info("Graph before layout:", JSON.stringify(write(b))), log.info("############################################# XXX"), log.info("###                Layout                 ### XXX"), log.info("############################################# XXX"), layout(b), log.info("Graph after layout:", JSON.stringify(write(b)));
	let P = 0, { subGraphTitleTotalMargin: F } = getSubGraphTitleMargins(D);
	return await Promise.all(sortNodesByHierarchy(b).map(async function(e) {
		let v = b.node(e);
		if (log.info("Position XBX => " + e + ": (" + v.x, "," + v.y, ") width: ", v.width, " height: ", v.height), v?.clusterNode) v.y += F, log.info("A tainted cluster node XBX1", e, v.id, v.width, v.height, v.x, v.y, b.parent(e)), clusterDb.get(v.id).node = v, positionNode(v);
		else if (b.children(e).length > 0) {
			log.info("A pure cluster node XBX1", e, v.id, v.x, v.y, v.width, v.height, b.parent(e)), v.height += F, b.node(v.parentId);
			let y = v?.padding / 2 || 0, x = v?.labelBBox?.height || 0, C = x - y || 0;
			log.debug("OffsetY", C, "labelHeight", x, "halfPadding", y), await insertCluster(A, v), clusterDb.get(v.id).node = v;
		} else {
			let e = b.node(v.parentId);
			v.y += F / 2, log.info("A regular node XBX1 - using the padding", v.id, "parent", v.parentId, v.width, v.height, v.x, v.y, "offsetY", v.offsetY, "parent", e, e?.offsetY, v), positionNode(v);
		}
	})), b.edges().forEach(function(e) {
		let v = b.edge(e);
		log.info("Edge " + e.v + " -> " + e.w + ": " + JSON.stringify(v), v), v.points.forEach((e) => e.y += F / 2), positionEdgeLabel(v, insertEdge(j, v, clusterDb, x, b.node(e.v), b.node(e.w), T));
	}), b.nodes().forEach(function(e) {
		let v = b.node(e);
		log.info(e, v.type, v.diff), v.isGroup && (P = v.diff);
	}), log.warn("Returning from recursive render XAX", k, P), {
		elem: k,
		diff: P
	};
}, "recursiveRender"), render = /* @__PURE__ */ __name(async (e, y) => {
	let S = new Graph({
		multigraph: !0,
		compound: !0
	}).setGraph({
		rankdir: e.direction,
		nodesep: e.config?.nodeSpacing || e.config?.flowchart?.nodeSpacing || e.nodeSpacing,
		ranksep: e.config?.rankSpacing || e.config?.flowchart?.rankSpacing || e.rankSpacing,
		marginx: 8,
		marginy: 8
	}).setDefaultEdgeLabel(function() {
		return {};
	}), C = y.select("g");
	markers_default(C, e.markers, e.type, e.diagramId), clear2(), clear(), clear$1(), clear4(), e.nodes.forEach((e) => {
		S.setNode(e.id, { ...e }), e.parentId && S.setParent(e.id, e.parentId);
	}), log.debug("Edges:", e.edges), e.edges.forEach((e) => {
		if (e.start === e.end) {
			let _ = e.start, v = _ + "---" + _ + "---1", y = _ + "---" + _ + "---2", b = S.node(_);
			S.setNode(v, {
				domId: v,
				id: v,
				parentId: b.parentId,
				labelStyle: "",
				label: "",
				padding: 0,
				shape: "labelRect",
				style: "",
				width: 10,
				height: 10
			}), S.setParent(v, b.parentId), S.setNode(y, {
				domId: y,
				id: y,
				parentId: b.parentId,
				labelStyle: "",
				padding: 0,
				shape: "labelRect",
				label: "",
				style: "",
				width: 10,
				height: 10
			}), S.setParent(y, b.parentId);
			let x = structuredClone(e), C = structuredClone(e), w = structuredClone(e);
			x.label = "", x.arrowTypeEnd = "none", x.id = _ + "-cyclic-special-1", C.arrowTypeStart = "none", C.arrowTypeEnd = "none", C.id = _ + "-cyclic-special-mid", w.label = "", b.isGroup && (x.fromCluster = _, w.toCluster = _), w.id = _ + "-cyclic-special-2", w.arrowTypeStart = "none", S.setEdge(_, v, x, _ + "-cyclic-special-0"), S.setEdge(v, y, C, _ + "-cyclic-special-1"), S.setEdge(y, _, w, _ + "-cyc<lic-special-2");
		} else S.setEdge(e.start, e.end, { ...e }, e.id);
	}), log.warn("Graph at first:", JSON.stringify(write(S))), adjustClustersAndEdges(S), log.warn("Graph after XAX:", JSON.stringify(write(S)));
	let w = getConfig2();
	await recursiveRender(C, S, e.type, e.diagramId, void 0, w);
}, "render");
export { render };
