// import dagre from '@dagrejs/dagre'
import dagre from 'dagre'
import { Position, useVueFlow } from '@vue-flow/core'
import { ref } from 'vue'

/**
 * Composable to run the layout algorithm on the graph.
 * It uses the `dagre` library to calculate the layout of the nodes and edges.
 */
export function useLayout() {
	const { findNode } = useVueFlow()

	const graph = ref(new dagre.graphlib.Graph())

	const previousDirection = ref('LR')

	function layout(nodes, edges, direction = 'LR', options) {
		const nodesep = options?.nodesep || 50 // 节点间距
		const ranksep = options?.ranksep || 50 // 层级间距
		// 验证和规范化方向参数
		const validDirections = ['TB', 'BT', 'LR', 'RL']
		const layoutDirection = validDirections.includes(direction) ? direction : 'LR'

		// we create a new graph instance, in case some nodes/edges were removed, otherwise dagre would act as if they were still there
		const dagreGraph = new dagre.graphlib.Graph()

		graph.value = dagreGraph

		dagreGraph.setDefaultEdgeLabel(() => ({}))

		// 根据方向判断是否为水平布局
		const isHorizontal = layoutDirection === 'LR' || layoutDirection === 'RL'
		dagreGraph.setGraph({
			rankdir: layoutDirection,
			nodesep,
			ranksep,
		})

		previousDirection.value = layoutDirection

		for (const node of nodes) {
			// if you need width+height of nodes for your layout, you can use the dimensions property of the internal node (`GraphNode` type)
			const graphNode = findNode(node.id)

			dagreGraph.setNode(node.id, {
				width: graphNode.dimensions.width || 150,
				height: graphNode.dimensions.height || 50
			})
		}

		for (const edge of edges) {
			dagreGraph.setEdge(edge.source, edge.target)
		}

		dagre.layout(dagreGraph)

		// set nodes with updated positions
		return nodes.map((node) => {
			const nodeWithPosition = dagreGraph.node(node.id)

			// 根据方向动态计算连接点位置
			let targetPosition, sourcePosition
			switch (layoutDirection) {
				case 'BT': // 从上到下 (Top to Bottom)
					targetPosition = Position.Bottom // 目标节点连接点在下方
					sourcePosition = Position.Top // 源节点连接点在上方
					break
				case 'TB': // 从下到上 (Bottom to Top)
					targetPosition = Position.Top // 目标节点连接点在上方
					sourcePosition = Position.Bottom // 源节点连接点在下方
					break
				case 'LR': // 从左到右 (Left to Right)
					targetPosition = Position.Left
					sourcePosition = Position.Right
					break
				case 'RL': // 从右到左 (Right to Left)
					targetPosition = Position.Right
					sourcePosition = Position.Left
					break
				default:
					targetPosition = Position.Top
					sourcePosition = Position.Bottom
			}
			return {
				...node,
				targetPosition,
				sourcePosition,
				position: { x: nodeWithPosition.x, y: nodeWithPosition.y }
			}
		})
	}

	return { graph, layout, previousDirection }
}
/**
 * 递归查找指定ID的节点并添加子节点
 * @param {Array} items - 要搜索的数组
 * @param {string} targetId - 要查找的节点ID
 * @param {Object} newChild - 要添加的新子节点
 * @returns {boolean} 是否成功添加
 */
export function findAndAddChild(items, targetId, newChild) {
	for (let i = 0; i < items.length; i++) {
		const item = items[i]

		// 如果找到目标节点
		if (item.id === targetId) {
			// 初始化child数组（如果不存在）
			if (!item.children) {
				item.children = []
			}
			// 添加新子节点
			item.children.push(newChild)
			return true
		}

		// 递归搜索子节点
		if (item.children && item.children.length > 0) {
			const found = findAndAddChild(item.children, targetId, newChild)
			if (found) return true
		}
	}

	return false
}
/**
 * 递归删除指定ID的节点
 * @param {Array} items - 要搜索的数组
 * @param {string} targetId - 要删除的节点ID
 * @returns {boolean} 是否成功删除
 */
export function findAndRemoveChild(items, targetId) {
	for (let i = 0; i < items.length; i++) {
		const item = items[i]

		// 如果找到目标节点，从当前数组中删除
		if (item.id === targetId) {
			items.splice(i, 1)
			return true
		}

		// 递归搜索子节点
		if (item.children && item.children.length > 0) {
			const found = findAndRemoveChild(item.children, targetId)
			if (found) return true
		}
	}

	return false
}