<script setup lang="ts">
import { ref, computed, nextTick, onMounted, onUpdated, watch } from 'vue'
import { VueFlow, useVueFlow, Handle, Position, type Node, type Edge } from '@vue-flow/core'
import '@vue-flow/core/dist/style.css'
import '@vue-flow/core/dist/theme-default.css'
import {
  useAgentsStore,
  useSelectionStore,
  type IRawStepTask,
  type TaskProcess,
  type IApiAgentAction
} from '@/stores'
import { getAgentMapIcon, getActionTypeDisplay } from '@/layout/components/config.ts'
import SvgIcon from '@/components/SvgIcon/index.vue'
import BranchInput from '@/components/BranchInput/index.vue'
import DeleteConfirmDialog from '@/components/DeleteConfirmDialog/index.vue'
import { ElTooltip, ElIcon, ElMessage } from 'element-plus'
import { CirclePlus, Remove } from '@element-plus/icons-vue'
import api from '@/api'
import { v4 as uuidv4 } from 'uuid'

const agentsStore = useAgentsStore()
const selectionStore = useSelectionStore()
const { onConnect, addEdges, fitView: fit } = useVueFlow()

// 直接从 store 获取当前任务和任务过程数据
const currentTask = computed(() => agentsStore.currentTask)!
const taskProcess = computed(() => agentsStore.currentTask?.TaskProcess ?? [])
const currentTaskContent = computed(() => agentsStore.currentTask?.TaskContent || '')

// 添加分支相关状态
const addingBranchNodeId = ref<string | null>(null)
const branchInputRef = ref<InstanceType<typeof BranchInput> | null>(null)

// 分支加载状态
const branchLoading = ref(false)

// 删除分支弹窗相关状态
const deleteDialogVisible = ref(false)
const branchIdToDelete = ref<string | null>(null)

// 删除单个节点弹窗相关状态
const deleteNodeDialogVisible = ref(false)
const nodeIdToDelete = ref<string | null>(null)

// 节点和边数据
const nodes = ref<Node[]>([])
const edges = ref<Edge[]>([])

// 边样式计算属性 - 与PlanModification.vue保持一致
const styledEdges = computed(() => {
  return edges.value.map(edge => {
    // 根节点永远参与高亮
    const sourceIsRoot = edge.source === 'root' || edge.source === 'root-goal'
    const targetIsRoot = edge.target === 'root' || edge.target === 'root-goal'
    const sourceSelected = selectedNodeIds.value.has(edge.source) || sourceIsRoot
    const targetSelected = selectedNodeIds.value.has(edge.target) || targetIsRoot
    const isHighlighted = sourceSelected && targetSelected

    return {
      ...edge,
      style: {
        stroke: isHighlighted ? 'var(--color-node-active)' : 'var(--color-node-border)',
        strokeWidth: 2
      },
      markerEnd: {
        type: 'arrow' as any,
        color: isHighlighted ? 'var(--color-node-active)' : 'var(--color-node-border)',
        width: 20,
        height: 20,
        strokeWidth: 2
      },
      class: isHighlighted ? 'edge-highlighted' : 'edge-normal'
    }
  })
})

//当前选中的节点ID集合
const selectedNodeIds = ref<Set<string>>(new Set())

// 用于防止重复同步的标志
let isSyncing = false

// 节点位置常量（与 PlanModification.vue 保持一致）
const START_X = 40
const START_Y = 50

//初始化标记，避免重复初始化
const BRANCHES_INIT_KEY_PREFIX = 'plan-task-branches-initialized-'

//最后选中的分支ID
const LAST_SELECTED_BRANCH_KEY = 'plan-task-last-selected-branch'

// ==================== 公共函数提取 ====================

// 获取 agent 个人简介
const getAgentProfile = (agentName: string): string => {
  return (
    agentsStore.agents.find((agent: any) => agent.Name === agentName)?.Profile || '暂无个人简介'
  )
}

// 创建 VueFlow 边的通用函数
const createFlowEdge = (
  source: string,
  target: string,
  sourceHandle: string = 'right',
  targetHandle: string = 'left',
  strokeColor: string = 'var(--color-node-border)',
  isFirstNode: boolean = false,
  branchId?: string
): Edge => {
  return {
    id: `edge-${source}-${target}`,
    source,
    target,
    sourceHandle,
    targetHandle,
    type: 'smoothstep',
    animated: true,
    style: {
      stroke: strokeColor,
      strokeWidth: 2,
      ...(isFirstNode ? { strokeDasharray: '5,5' } : {})
    },
    markerEnd: {
      type: 'arrow' as any,
      color: 'var(--color-node-border)',
      width: 20,
      height: 20,
      strokeWidth: 2
    },
    data: branchId ? { branchId } : undefined
  }
}

// 创建分支 agent 节点的通用函数
const createBranchAgentNode = (
  agentNodeId: string,
  action: IApiAgentAction,
  position: { x: number; y: number }
): Node => {
  const agentInfo = getAgentMapIcon(action.agent)
  const actionTypeInfo = getActionTypeDisplay(action.type)
  const agentProfile = getAgentProfile(action.agent)

  return {
    id: agentNodeId,
    type: 'agent',
    position,
    data: {
      agentName: action.agent,
      agentIcon: agentInfo.icon,
      agentColor: agentInfo.color,
      actionTypeColor: actionTypeInfo?.color || '#909399',
      agentDescription: action.description || '暂无描述',
      agentProfile: agentProfile,
      actionTypeName: actionTypeInfo?.name || '未知职责',
      actionTypeKey: actionTypeInfo?.key || 'unknown',
      isRoot: false,
      isBranchTask: true
    }
  }
}

// 保存分支到 store 的通用函数
const saveBranchToStore = (
  branchType: 'root' | 'task',
  branchContent: string,
  newBranchNodes: Node[],
  newBranchEdges: Edge[],
  branchTasks: any[]
) => {
  if (newBranchNodes.length === 0) return

  const taskStepId = currentTask.value?.Id || ''
  const currentAgents = currentTask.value?.AgentSelection || []

  isSyncing = true
  selectionStore.addTaskProcessBranch(taskStepId, currentAgents, {
    parentNodeId: addingBranchNodeId.value!,
    branchContent,
    branchType,
    nodes: JSON.parse(JSON.stringify(newBranchNodes)),
    edges: JSON.parse(JSON.stringify(newBranchEdges)),
    tasks: JSON.parse(JSON.stringify(branchTasks))
  })

  setTimeout(() => {
    isSyncing = false
  }, 300)

  saveTaskProcessBranchesToDB()
}

// 解析分支 API 响应的通用函数
const parseBranchResponse = (response: any): IApiAgentAction[] => {
  const newAgentActions: IApiAgentAction[] = []
  const responseData = response.data || response

  if (responseData && responseData.length > 0) {
    const firstBranch = responseData[0]
    firstBranch.forEach((action: any) => {
      newAgentActions.push({
        id: action.ID || uuidv4(),
        type: action.ActionType,
        agent: action.AgentName,
        description: action.Description,
        inputs: action.ImportantInput || []
      })
    })
  }

  return newAgentActions
}

// 获取主流程节点 ID 列表的通用函数
const getMainProcessNodeIds = (nodeList?: Node[]): string[] => {
  const targetNodes = nodeList || nodes.value
  return targetNodes.filter(n => !n.data.isBranchTask && n.id !== 'root').map(n => n.id)
}

// 设置主流程高亮的通用函数
const highlightMainProcess = (nodeList?: Node[]) => {
  const mainProcessNodes = getMainProcessNodeIds(nodeList)
  selectedNodeIds.value = new Set(mainProcessNodes)
}

// 创建分支节点和边的通用函数
const createBranchNodesAndEdges = (
  newAgentActions: IApiAgentAction[],
  branchStartX: number,
  branchStartY: number,
  parentNodeId: string,
  strokeColor: string = '#67c23a',
  branchId?: string
): { nodes: Node[]; edges: Edge[] } => {
  const newBranchNodes: Node[] = []
  const newBranchEdges: Edge[] = []
  const timestamp = Date.now()
  const agentNodeIds: string[] = []
  // 使用传入的 branchId 或 timestamp 作为分支ID
  const currentBranchId = branchId || String(timestamp)

  newAgentActions.forEach((action, index) => {
    const agentNodeId = `branch-agent-${parentNodeId}-${timestamp}-${index}`
    agentNodeIds.push(agentNodeId)

    // 计算位置：横向排列（根据节点宽度调整偏移）
    // 节点宽度约150px，加上间隙80px，所以偏移250px
    const nodeX = branchStartX + (parentNodeId === 'root' ? 250 : 100) + index * 220
    const nodeY = branchStartY

    // 创建 agent 节点
    const newAgentNode = createBranchAgentNode(agentNodeId, action, { x: nodeX, y: nodeY })
    nodes.value.push(newAgentNode)
    newBranchNodes.push(newAgentNode)

    // 创建连接边
    if (index === 0) {
      // 第一个 agent 连接到父节点，需要设置 branchId
      const newEdge = createFlowEdge(
        parentNodeId,
        agentNodeId,
        'bottom',
        'left',
        strokeColor,
        true,
        currentBranchId
      )
      edges.value.push(newEdge)
      newBranchEdges.push(newEdge)
    } else {
      // 后续 agent 连接到前一个 agent
      const prevAgentNodeId = agentNodeIds[index - 1]!
      const newEdge = createFlowEdge(
        prevAgentNodeId,
        agentNodeId,
        'right',
        'left',
        strokeColor,
        false
      )
      edges.value.push(newEdge)
      newBranchEdges.push(newEdge)
    }
  })

  return { nodes: newBranchNodes, edges: newBranchEdges }
}

// ==================== 原有函数保持不变 ====================

// 获取分支的所有节点
const getAllBranchNodes = (startNodeId: string): string[] => {
  const visited = new Set<string>()
  const toVisit: string[] = [startNodeId]

  while (toVisit.length > 0) {
    const currentId = toVisit.shift()!

    if (visited.has(currentId)) {
      continue
    }
    visited.add(currentId)

    // 只查找通过 right handle 连接的后续节点
    const outgoingEdges = edges.value.filter(
      edge => edge.source === currentId && edge.sourceHandle === 'right'
    )

    for (const edge of outgoingEdges) {
      const targetNodeId = edge.target
      // 只访问分支节点
      if (
        !visited.has(targetNodeId) &&
        targetNodeId !== 'root' &&
        nodes.value.find(n => n.id === targetNodeId)?.data.isBranchTask
      ) {
        toVisit.push(targetNodeId)
      }
    }
  }

  return Array.from(visited)
}

//获取从指定节点回溯到根节点的路径（只包含主流程节点）
const getPathToRoot = (targetNodeId: string): string[] => {
  const path: string[] = []
  const visited = new Set<string>()
  const queue: Array<{ nodeId: string; path: string[] }> = []

  queue.push({ nodeId: targetNodeId, path: [targetNodeId] })

  while (queue.length > 0) {
    const { nodeId: currentId, path: currentPath } = queue.shift()!

    if (currentId === 'root') {
      // 找到根节点，返回路径（排除根节点本身）
      return currentPath.filter(id => id !== 'root')
    }

    if (visited.has(currentId)) {
      continue
    }
    visited.add(currentId)

    // 只查找指向当前节点的边（回溯）
    const incomingEdges = edges.value.filter(edge => edge.target === currentId)

    for (const edge of incomingEdges) {
      // 只沿着非分支节点回溯（主流程节点）
      const sourceNode = nodes.value.find(n => n.id === edge.source)
      if (sourceNode && !sourceNode.data.isBranchTask) {
        const newPath = [edge.source, ...currentPath]
        queue.push({ nodeId: edge.source, path: newPath })
      }
    }
  }

  return path
}

// 向上回溯分支的父节点链（只包含分支节点）
const getBranchParentChain = (targetNodeId: string): string[] => {
  const parentChain: string[] = []
  let currentId = targetNodeId

  while (currentId && currentId !== 'root') {
    // 查找指向当前节点的边
    const incomingEdge = edges.value.find(edge => edge.target === currentId)

    if (!incomingEdge) {
      break
    }

    const sourceNode = nodes.value.find(n => n.id === incomingEdge.source)

    // 如果父节点不是分支节点，停止回溯
    if (!sourceNode || !sourceNode.data.isBranchTask) {
      break
    }

    // 添加父节点到链中
    parentChain.push(sourceNode.id)
    currentId = sourceNode.id
  }

  return parentChain
}

// 判断节点是否可删除（分支从底部出发连接的节点）
const getNodeDeletable = (
  nodeId: string
): { isDeletable: boolean; branchId: string | null; parentNodeId: string | null } => {
  // 直接从 store 的分支数据里用节点 id 查找它属于哪个分支
  const taskStepId = currentTask.value?.Id
  const currentAgents = currentTask.value?.AgentSelection || []

  if (!taskStepId) {
    return {
      isDeletable: false,
      branchId: null,
      parentNodeId: null
    }
  }

  // 获取所有分支数据
  const savedBranches = selectionStore.getTaskProcessBranches(taskStepId, currentAgents)

  // 遍历所有分支，用节点 id 在 nodes 数组中查找
  for (const branch of savedBranches) {
    // 检查该节点是否是该分支的第一个节点
    const firstNode = branch.nodes?.[0]
    if (firstNode && firstNode.id === nodeId) {
      // 只有该分支的第一个节点才显示删除分支按钮
      return {
        isDeletable: true,
        branchId: branch.id,
        parentNodeId: branch.parentNodeId || null
      }
    }
  }

  return {
    isDeletable: false,
    branchId: null,
    parentNodeId: null
  }
}

// 删除分支（显示确认对话框）
const handleDeleteBranch = (nodeId: string) => {
  // 获取节点的删除信息（包括 parentNodeId）
  const nodeInfo = getNodeDeletable(nodeId)
  if (!nodeInfo.isDeletable || !nodeInfo.parentNodeId) {
    ElMessage.error('无法删除该分支')
    return
  }

  const taskStepId = currentTask.value?.Id
  const currentAgents = currentTask.value?.AgentSelection || []

  if (!taskStepId) return

  // 通过 branchId 查找正确的分支（使用 branchId 精确匹配，而不是 parentNodeId）
  const savedBranches = selectionStore.getTaskProcessBranches(taskStepId, currentAgents)
  const targetBranch = savedBranches.find(branch => branch.id === nodeInfo.branchId)

  if (!targetBranch) {
    ElMessage.error('未找到该分支')
    return
  }

  console.log(
    '[删除分支] 找到的 branchId:',
    targetBranch.id,
    'parentNodeId:',
    nodeInfo.parentNodeId
  )
  branchIdToDelete.value = targetBranch.id
  deleteDialogVisible.value = true
}

// 确认删除分支
const confirmDeleteBranch = async () => {
  if (!branchIdToDelete.value) return

  const branchId = branchIdToDelete.value
  const taskStepId = currentTask.value?.Id!
  const currentAgents = currentTask.value?.AgentSelection || []

  // 1. 从store中获取该分支的信息
  const savedBranches = selectionStore.getTaskProcessBranches(taskStepId, currentAgents)
  const branchToDelete = savedBranches.find(branch => branch.id === branchId)

  if (!branchToDelete) {
    ElMessage.error('未找到该分支')
    deleteDialogVisible.value = false
    return
  }

  // 2. 获取该分支的所有节点ID
  const branchNodeIds = branchToDelete.nodes ? branchToDelete.nodes.map((node: any) => node.id) : []

  // 3. 获取该分支的所有边ID
  const branchEdgeIds = branchToDelete.edges ? branchToDelete.edges.map((edge: any) => edge.id) : []

  // 4. 从nodes中删除该分支的所有节点
  nodes.value = nodes.value.filter(node => !branchNodeIds.includes(node.id))

  // 5. 从edges中删除该分支的所有边
  edges.value = edges.value.filter(edge => !branchEdgeIds.includes(edge.id))

  // 6. 从selectionStore中删除该分支
  selectionStore.removeTaskProcessBranch(taskStepId, currentAgents, branchId)

  // 7. 从数据库中删除该分支
  const TaskID = (window as any).__CURRENT_TASK_ID__
  if (TaskID) {
    await selectionStore.deleteTaskProcessBranchFromDB(TaskID, taskStepId, branchId)
  }

  // 8. 刷新视图
  nextTick(() => {
    fit({ padding: 0.15, duration: 300 })
  })

  // 9. 关闭对话框并清理状态
  deleteDialogVisible.value = false
  branchIdToDelete.value = null

  ElMessage.success('分支删除成功')
}

// 删除单个节点（显示确认对话框）
const handleDeleteNode = (nodeId: string) => {
  nodeIdToDelete.value = nodeId
  deleteNodeDialogVisible.value = true
}

// 确认删除单个节点
const confirmDeleteNode = async () => {
  if (!nodeIdToDelete.value) return

  const nodeId = nodeIdToDelete.value
  const taskStepId = currentTask.value?.Id
  const currentAgents = currentTask.value?.AgentSelection || []

  // 0. 检查被删除的节点是否是分支的第一个节点（带删除分支按钮）
  const nodeDeletable = getNodeDeletable(nodeId)
  const deletedBranchId = nodeDeletable.isDeletable ? nodeDeletable.branchId : null

  // 1. 找到该节点的入边和出边
  const incomingEdges = edges.value.filter(e => e.target === nodeId)
  const outgoingEdges = edges.value.filter(e => e.source === nodeId)

  // 1.1 保存删除前的子节点信息（用于后续更新 branchId）
  const childNodeIds = outgoingEdges.map(e => e.target)

  // 2. 将子节点重新连接到父节点（使用固定的 left/right handle）
  const newEdges: Edge[] = []
  outgoingEdges.forEach(outEdge => {
    incomingEdges.forEach(inEdge => {
      // 创建新边，连接父节点（右侧）到子节点（左侧）
      const newEdge = {
        id: `e-${inEdge.source}-${outEdge.target}-${Date.now()}`,
        source: inEdge.source,
        target: outEdge.target,
        sourceHandle: 'right', // 父节点右侧
        targetHandle: 'left', // 子节点左侧
        type: 'smoothstep',
        animated: true,
        style: outEdge.style,
        markerEnd: outEdge.markerEnd,
        data: inEdge.data // 保留父节点的 branchId
      }
      edges.value.push(newEdge)
      newEdges.push(newEdge)
    })
  })

  // 3. 删除该节点的入边和出边
  const relatedEdgeIds = [...incomingEdges.map(e => e.id), ...outgoingEdges.map(e => e.id)]
  edges.value = edges.value.filter(e => !relatedEdgeIds.includes(e.id))

  // 4. 删除该节点
  nodes.value = nodes.value.filter(n => n.id !== nodeId)

  // 4.1 如果删除的是分支的第一个节点，需要更新新第一个节点的边信息
  if (deletedBranchId && childNodeIds.length > 0) {
    // 遍历所有子节点，更新它们的入边信息
    childNodeIds.forEach(childNodeId => {
      // 找到连接子节点的入边
      const childIncomingEdge = edges.value.find(
        e => e.target === childNodeId && e.sourceHandle === 'right'
      )
      if (childIncomingEdge) {
        // 更新边的 sourceHandle 为 'bottom' 并添加 branchId，使新节点成为可删除分支的入口
        childIncomingEdge.sourceHandle = 'bottom'
        childIncomingEdge.data = {
          ...childIncomingEdge.data,
          branchId: deletedBranchId
        }
        console.log('[删除节点] 已更新新节点的边信息:', childNodeId, deletedBranchId)
      }
    })
  }

  // 5. 精准删除 store 中对应分支的节点数据，并调用后端接口删除
  if (taskStepId && currentAgents.length > 0) {
    // 获取所有分支数据
    const branches = selectionStore.getTaskProcessBranches(taskStepId, currentAgents)

    // 找到被删除节点所属的分支
    const targetBranch = branches.find(branch => branch.nodes?.some((n: any) => n.id === nodeId))

    if (targetBranch) {
      // 使用精准删除方法（前端 store）
      const success = selectionStore.removeNodeFromBranch(
        taskStepId,
        currentAgents,
        targetBranch.id,
        nodeId,
        incomingEdges,
        outgoingEdges,
        newEdges
      )

      if (success) {
        console.log('[删除节点] 前端精准删除成功')

        // 调用后端接口删除节点，传递更新后的 edges 数据
        const TaskID = (window as any).__CURRENT_TASK_ID__
        if (TaskID) {
          const result = await selectionStore.deleteTaskProcessNodeFromDB(
            TaskID,
            taskStepId,
            targetBranch.id,
            nodeId,
            edges.value
          )
          console.log('[删除节点] 后端删除结果:', result)
        }
      } else {
        console.error('[删除节点] 前端精准删除失败')
      }
    } else {
      console.error('[删除节点] 未找到节点所属的分支')
    }
  } else {
    console.error('[删除节点] 缺少 taskStepId 或 currentAgents')
  }

  // 6. 刷新视图
  nextTick(() => {
    fit({ padding: 0.15, duration: 300 })
  })

  // 7. 清理状态
  deleteNodeDialogVisible.value = false
  nodeIdToDelete.value = null

  ElMessage.success('节点删除成功')
}

// 初始化流程图
const initializeFlow = () => {
  if (!currentTask.value) {
    nodes.value = []
    edges.value = []
    return
  }

  // 获取当前流程数据
  const taskStepId = currentTask.value.Id!
  // 获取当前 agent 组合（用于区分不同 agent 组合的分支数据）
  const currentAgents = currentTask.value.AgentSelection || []

  // 优先从 store 获取"初始流程"的原始数据，保证数据正确性
  const savedBranches = selectionStore.getTaskProcessBranches(taskStepId, currentAgents)
  const initialBranch = savedBranches.find(branch => branch.branchContent === '初始流程')
  const rawTaskProcess = initialBranch?.tasks || taskProcess.value

  // 立即保存为副本（深拷贝）
  const taskProcessCopy = JSON.parse(JSON.stringify(rawTaskProcess))

  // 使用副本数据创建节点
  const taskProcessForNodes = taskProcessCopy
  const newNodes: Node[] = []
  const newEdges: Edge[] = []

  // 添加根节点（与 PlanModification.vue 一致）
  newNodes.push({
    id: 'root',
    type: 'root',
    position: { x: START_X, y: START_Y - 2 },
    data: {
      isRoot: true
    }
  })

  // 添加 agent 节点（与 PlanModification.vue 一致）
  taskProcessForNodes.forEach((process: any, index: number) => {
    const agentInfo = getAgentMapIcon(process.AgentName)
    const actionTypeInfo = getActionTypeDisplay(process.ActionType)

    // 从 agentsStore 中获取 agent 的个人简介
    const agentProfile =
      agentsStore.agents.find((agent: any) => agent.Name === process.AgentName)?.Profile ||
      '暂无个人简介'

    // 计算位置：START_X + ROOT_WIDTH + NODE_GAP + index * (NODE_WIDTH + NODE_GAP)
    // = 40 + 200 + 80 + index * (120 + 80) = 320 + index * 200
    const nodeWidth = 120
    const rootWidth = 200
    const nodeGap = 80

    newNodes.push({
      id: `agent-${index}`,
      type: 'agent',
      position: {
        x: START_X + rootWidth + nodeGap + index * (nodeWidth + nodeGap),
        y: START_Y
      },
      data: {
        agentName: process.AgentName,
        agentIcon: agentInfo.icon,
        agentColor: agentInfo.color,
        actionTypeColor: actionTypeInfo?.color || '#909399',
        agentDescription: process.Description || '暂无描述',
        agentProfile: agentProfile,
        actionTypeName: actionTypeInfo?.name || '未知职责',
        actionTypeKey: actionTypeInfo?.key || 'unknown',
        isRoot: false,
        originalIndex: index // 记录原始索引
      }
    })
  })

  // 添加边
  // 根节点连接到第一个 agent
  if (taskProcessForNodes.length > 0) {
    newEdges.push({
      id: 'edge-root-0',
      source: 'root',
      sourceHandle: 'right',
      target: 'agent-0',
      targetHandle: 'left',
      type: 'smoothstep',
      animated: true,
      style: { stroke: '#43a8aa', strokeWidth: 2 },
      markerEnd: {
        type: 'arrow' as any,
        color: '#43a8aa',
        width: 20,
        height: 20,
        strokeWidth: 2
      }
    })
  }

  // agent 之间依次连接
  for (let i = 0; i < taskProcessForNodes.length - 1; i++) {
    newEdges.push({
      id: `edge-${i}`,
      source: `agent-${i}`,
      sourceHandle: 'right',
      target: `agent-${i + 1}`,
      targetHandle: 'left',
      type: 'smoothstep',
      animated: true,
      style: { stroke: '#43a8aa', strokeWidth: 2 },
      markerEnd: {
        type: 'arrow' as any,
        color: '#43a8aa',
        width: 20,
        height: 20,
        strokeWidth: 2
      }
    })
  }

  nodes.value = newNodes
  edges.value = newEdges

  // 从 store 恢复已保存的任务过程分支数据

  if (taskStepId) {
    //  使用当前 agent 组合获取分支数据
    const savedBranches = selectionStore.getTaskProcessBranches(taskStepId, currentAgents)

    // 检查是否已经初始化过（针对该任务和 agent 组合）
    const branchesInitKey = `${BRANCHES_INIT_KEY_PREFIX}${taskStepId}_${selectionStore.getAgentGroupKey(
      currentAgents
    )}`
    const branchesInitialized = sessionStorage.getItem(branchesInitKey) === 'true'

    // 【修复】优先检查 store 中是否有数据，而不是依赖 sessionStorage 标记
    // 原逻辑：if (branchesInitialized && savedBranches.length > 0)
    // 问题：从历史记录恢复时，store 有数据但 sessionStorage 无标记，导致重复创建"初始流程"分支
    if (savedBranches.length > 0) {
      // 先创建根节点和主流程节点（作为分支的基础）
      nodes.value = newNodes
      edges.value = newEdges

      // 找出非初始流程的分支
      const actualBranches = savedBranches.filter(branch => branch.branchContent !== '初始流程')

      // 恢复分支：直接使用数据库中保存的位置，不再重新计算
      actualBranches.forEach(branch => {
        // 恢复节点，直接使用保存的位置
        branch.nodes.forEach(node => {
          // 跳过根节点（已经在 newNodes 中）
          if (node.id !== 'root') {
            const restoredNode = JSON.parse(JSON.stringify(node))
            // 直接使用数据库中保存的位置
            nodes.value.push(restoredNode)
          }
        })
        // 恢复边，并为第一个连接到父节点的边添加 branchId
        branch.edges.forEach((edge, edgeIndex) => {
          const restoredEdge = JSON.parse(JSON.stringify(edge))
          // 第一个边（连接到父节点）需要添加 branchId
          if (edgeIndex === 0) {
            restoredEdge.data = { ...restoredEdge.data, branchId: branch.id }
          }
          edges.value.push(restoredEdge)
        })
      })

      // 【修复】补充标记已初始化，避免后续重复创建"初始流程"分支
      if (!branchesInitialized) {
        sessionStorage.setItem(branchesInitKey, 'true')
      }

      //  恢复最后选中的分支
      const lastSelectedBranchId = sessionStorage.getItem(LAST_SELECTED_BRANCH_KEY)
      if (lastSelectedBranchId) {
        const lastSelectedBranch = savedBranches.find(branch => branch.id === lastSelectedBranchId)
        if (lastSelectedBranch) {
          // 恢复高亮状态
          let nodesToHighlight: string[] = []

          if (lastSelectedBranch.branchContent === '初始流程') {
            // 初始流程：高亮所有主流程节点（从恢复的nodes中获取）
            nodesToHighlight = getMainProcessNodeIds()
          } else {
            // 其他分支：高亮主流程路径 + 分支节点（支持多级分支）
            const firstBranchNode = lastSelectedBranch.nodes[0]
            if (firstBranchNode) {
              // 找到连接到该分支的第一个节点的边（从恢复的edges中查找）
              const incomingEdge = edges.value.find(edge => edge.target === firstBranchNode.id)
              if (incomingEdge) {
                // 回溯主流程路径
                let currentNode = nodes.value.find(n => n.id === incomingEdge.source)
                while (currentNode && currentNode.id !== 'root') {
                  nodesToHighlight.unshift(currentNode.id)
                  const prevEdge = edges.value.find(e => e.target === currentNode?.id)
                  currentNode = prevEdge
                    ? nodes.value.find(n => n.id === prevEdge.source)
                    : undefined
                }
              }

              // 获取父节点链和子节点
              const branchParentChain = getBranchParentChain(firstBranchNode.id)
              const branchChildNodes = getAllBranchNodes(firstBranchNode.id)

              // 合并：父节点链 + 子节点
              nodesToHighlight.push(...branchParentChain, ...branchChildNodes)
            }
          }

          selectedNodeIds.value = new Set(nodesToHighlight)
        } else {
          // 找不到最后选中的分支，默认选中初始流程的高亮状态
          highlightMainProcess()
        }
      } else {
        // 没有保存的选中分支，默认选中初始流程的高亮状态
        highlightMainProcess()
      }
    } else {
      // 首次初始化：设置节点和边，并保存为"初始流程"分支
      nodes.value = newNodes
      edges.value = newEdges

      const initialBranchNodes = newNodes
      const initialBranchEdges = [...newEdges]

      const initialBranchId = selectionStore.addTaskProcessBranch(taskStepId, currentAgents, {
        parentNodeId: 'root',
        branchContent: '初始流程',
        branchType: 'root',
        nodes: JSON.parse(JSON.stringify(initialBranchNodes)),
        edges: JSON.parse(JSON.stringify(initialBranchEdges)),
        tasks: taskProcessCopy
      })

      //  标记已初始化（针对该任务步骤和 agent 组合）
      sessionStorage.setItem(branchesInitKey, 'true')

      // 保存任务过程分支到数据库
      saveTaskProcessBranchesToDB()

      //  首次初始化时，设置初始流程为当前选中分支
      selectionStore.setActiveTaskProcessBranch(taskStepId, currentAgents, initialBranchId)

      // 默认选中"初始流程"的高亮状态
      highlightMainProcess(newNodes)
    }
  }
}

// 组件挂载后初始化
onMounted(() => {
  if (currentTask.value) {
    initializeFlow()
    // 适应视图 - 增加padding让节点显示更小
    nextTick(() => {
      setTimeout(() => {
        fit({ padding: 0.4, duration: 300 })
      }, 300)
    })
  }
})

// 组件更新后（v-show显示时）重新适应视图
onUpdated(() => {
  nextTick(() => {
    setTimeout(() => {
      fit({ padding: 0.4, duration: 300 })
    }, 300)
  })
})

// 监听 currentTask 变化，实时更新流程图
watch(
  () => currentTask.value?.Id,
  (newTaskId, oldTaskId) => {
    if (newTaskId && newTaskId !== oldTaskId) {
      // 任务切换时重新初始化
      nextTick(() => {
        initializeFlow()
        setTimeout(() => {
          fit({ padding: 0.4, duration: 300 })
        }, 300)
      })
    }
  }
)

// 监听 taskProcess 变化，更新流程图节点数据
watch(
  () => taskProcess.value,
  () => {
    // TaskProcess 变化时重新初始化（保持与其他页面联动）
    if (currentTask.value) {
      nextTick(() => {
        initializeFlow()
        setTimeout(() => {
          fit({ padding: 0.4, duration: 300 })
        }, 300)
      })
    }
  },
  { deep: true }
)

// 分支添加相关方法
const startAddBranch = (nodeId: string) => {
  addingBranchNodeId.value = nodeId
  nextTick(() => {
    branchInputRef.value?.focus()
  })
}

const cancelAddBranch = () => {
  addingBranchNodeId.value = null
}

// 节点点击事件
const onNodeClick = (event: any) => {
  const nodeId = event.node.id
  const nodeData = event.node.data as any

  // 如果点击的是根节点，不做处理（根节点不参与高亮）
  if (nodeId === 'root') {
    return
  }

  // 判断是否是分支节点
  const isBranchNode = nodeData.isBranchTask

  if (isBranchNode) {
    // 点击的是分支节点
    // 向上回溯分支父节点链（多级分支）
    const branchParentChain = getBranchParentChain(nodeId)

    // 向下遍历分支的子节点（只沿right handle方向）
    const branchChildNodes = getAllBranchNodes(nodeId)

    // 找到最顶层的分支父节点（连接到主流程或根节点的）
    let topBranchNodeId: string | null = null
    if (branchParentChain.length > 0) {
      // 取父节点链的最后一个（最顶层的分支节点）
      topBranchNodeId = branchParentChain[branchParentChain.length - 1]!
    } else {
      // 如果没有分支父节点，当前节点就是最顶层
      topBranchNodeId = nodeId
    }

    // 找到最顶层分支节点的父节点（主流程节点或根节点）
    let parentNodeId: string | null = null
    const topBranchIncomingEdge = edges.value.find(edge => edge.target === topBranchNodeId)

    if (topBranchIncomingEdge) {
      parentNodeId = topBranchIncomingEdge.source
    }

    if (parentNodeId) {
      // 回溯到根节点，获取主流程路径
      const pathToRoot = getPathToRoot(parentNodeId)

      // getPathToRoot 已经返回正序（从左到右），不需要反转
      const correctPathToRoot = pathToRoot // [agent-0, agent-1, agent-2, ...]
      const correctBranchParentChain = [...branchParentChain].reverse() // 顶层分支 → ... → 直接父分支（正序）

      // 合并：主流程路径（正序） + 分支父节点链（正序） + 分支子节点（正序）
      const allNodesToHighlight = [
        ...correctPathToRoot,
        ...correctBranchParentChain,
        ...branchChildNodes
      ]
      selectedNodeIds.value = new Set(allNodesToHighlight)

      // 保存完整的 TaskProcess 数据（主流程 + 分支）到 store
      if (currentTask.value) {
        const completeTaskProcess: any[] = []

        // 类型守卫：检查是否为 TaskProcess 类型（有 Description 字段）
        const isTaskProcess = (data: any): data is TaskProcess => data && 'Description' in data

        // 从 store 中获取"初始流程"副本（而不是使用 taskProcess.value）
        const taskStepId = currentTask.value.Id!
        const currentAgents = currentTask.value.AgentSelection || []
        const branches = selectionStore.getTaskProcessBranches(taskStepId, currentAgents)
        const initialBranch = branches.find(branch => branch.branchContent === '初始流程')
        const mainProcessData = initialBranch?.tasks || taskProcess.value

        // 按照高亮路径顺序收集每个节点的数据
        allNodesToHighlight.forEach(nodeId => {
          const node = nodes.value.find(n => n.id === nodeId)

          if (!node) return

          // 判断是主流程节点还是分支节点
          if (!node.data.isBranchTask && node.data.originalIndex !== undefined) {
            // 主流程节点：从初始流程数据中获取
            const originalIndex = node.data.originalIndex
            const processData = mainProcessData[originalIndex]
            if (
              processData &&
              isTaskProcess(processData) &&
              processData.ID &&
              processData.AgentName &&
              processData.Description
            ) {
              completeTaskProcess.push(processData)
            }
          } else if (node.data.isBranchTask) {
            // 分支节点：从对应的分支数据中获取（按索引匹配）
            const parentBranch = branches.find(branch => branch.nodes.some(n => n.id === nodeId))

            if (parentBranch && parentBranch.tasks) {
              // 找到该节点在分支节点列表中的索引
              const nodeIndex = parentBranch.nodes.findIndex(n => n.id === nodeId)
              if (nodeIndex !== -1 && parentBranch.tasks[nodeIndex]) {
                const taskData = parentBranch.tasks[nodeIndex]
                if (
                  isTaskProcess(taskData) &&
                  taskData.ID &&
                  taskData.AgentName &&
                  taskData.Description
                ) {
                  completeTaskProcess.push(taskData)
                }
              }
            }
          }
        })

        // 找到当前点击节点所属的分支，用于保存选中状态
        const matchedBranch = branches.find(branch => {
          return branch.nodes.some(node => node.id === nodeId)
        })

        if (matchedBranch) {
          sessionStorage.setItem(LAST_SELECTED_BRANCH_KEY, matchedBranch.id)
        }

        selectionStore.setActiveTaskProcessData(taskStepId, currentAgents, completeTaskProcess)
        agentsStore.setCurrentTaskProcess(completeTaskProcess)
      }
    } else {
      // 如果找不到父节点，只高亮分支节点
      const allBranchNodes = [...branchParentChain, ...branchChildNodes]
      selectedNodeIds.value = new Set(allBranchNodes)
    }
  } else {
    // 点击的是主流程节点，高亮所有主流程节点（初始流程）
    highlightMainProcess()

    // 点击主流程节点时，从 store 读取"初始流程"分支的副本
    if (currentTask.value) {
      const taskStepId = currentTask.value.Id
      if (!taskStepId) {
        return
      }
      const currentAgents = currentTask.value.AgentSelection || []
      const branches = selectionStore.getTaskProcessBranches(taskStepId, currentAgents)
      const initialBranch = branches.find(branch => branch.branchContent === '初始流程')

      if (initialBranch && initialBranch.tasks) {
        // 使用 store 中保存的初始流程副本
        selectionStore.setActiveTaskProcessData(taskStepId, currentAgents, initialBranch.tasks)

        // 同步更新 currentTask.TaskProcess（实现全局数据联动）
        agentsStore.setCurrentTaskProcess(initialBranch.tasks as unknown as TaskProcess[])

        // 保存选中的分支ID到 sessionStorage
        sessionStorage.setItem(LAST_SELECTED_BRANCH_KEY, initialBranch.id)
      } else {
        // 降级：使用 taskProcess.value
        const originalTaskProcess = taskProcess.value
        selectionStore.setActiveTaskProcessData(taskStepId, currentAgents, originalTaskProcess)

        // 同步更新 currentTask.TaskProcess（实现全局数据联动）
        agentsStore.setCurrentTaskProcess(originalTaskProcess)
      }
    }
  }
}

// 添加分支
const submitBranch = async (branchContent: string) => {
  if (!branchContent.trim() || !addingBranchNodeId.value) return

  const parentNodeId = addingBranchNodeId.value

  // 获取父节点
  const parentNode = nodes.value.find((n: Node) => n.id === parentNodeId)
  if (!parentNode) {
    ElMessage.error('找不到父节点')
    return
  }

  // 开始加载
  branchLoading.value = true

  try {
    // 计算新分支的起始位置：基于同一父节点下已有的分支数量
    const parentNodeId = addingBranchNodeId.value!
    const isRootBranch = parentNodeId === 'root'
    const baseOffset = isRootBranch ? 200 : 150

    // 获取当前任务的所有分支
    if (currentTask.value?.Id) {
      const taskStepId = currentTask.value.Id
      const currentAgents = currentTask.value.AgentSelection || []
      const savedBranches = selectionStore.getTaskProcessBranches(taskStepId, currentAgents)

      // 找到同一父节点下的所有现有分支
      const sameParentBranches = savedBranches.filter(b => b.parentNodeId === parentNodeId)

      // 新分支的数量 = 现有分支数量
      const newBranchIndex = sameParentBranches.length

      // 计算该父节点在主流程中的位置索引（用于区分不同父节点的分支）
      let parentNodeIndex = 0
      if (!isRootBranch) {
        const parentNode = nodes.value.find((n: Node) => n.id === parentNodeId)
        if (parentNode) {
          parentNodeIndex = parentNode.data.originalIndex || 0
        }
      }

      // 根据分支索引重新计算所有分支的位置并保存
      // 每个父节点的分支使用不同的Y偏移范围，避免重叠
      sameParentBranches.forEach((branch, index) => {
        // 根节点分支加500偏移，避免和agent分支重叠
        const rootOffset = isRootBranch ? 500 : 0
        // 基础Y + 同一父节点内的分支偏移 + 不同父节点的额外偏移 + 根节点额外偏移
        const newY =
          parentNode.position.y + baseOffset + index * 250 + parentNodeIndex * 100 + rootOffset

        // 更新 UI 中的节点位置
        branch.nodes.forEach(node => {
          if (node.data?.isBranchTask) {
            const uiNode = nodes.value.find(n => n.id === node.id)
            if (uiNode) {
              uiNode.position.y = newY
            }
            node.position.y = newY
          }
        })
      })
    }

    // 用于存储新创建的分支节点和边
    const newBranchNodes: Node[] = []
    const newBranchEdges: Edge[] = []

    // 判断是根节点还是 agent 节点
    if (parentNodeId === 'root') {
      // 根节点分支

      // 调用真实 API
      const generalGoal = agentsStore.agentRawPlan.data?.['General Goal'] || ''

      // 根节点分支：从零开始生成完整方案
      // Baseline_Completion = 0 表示没有已完成的部分，需要生成所有阶段
      // Existing_Steps 传空数组，不传递初始流程信息
      const response = await api.branchTaskProcess({
        branch_Number: 1,
        Modification_Requirement: branchContent,
        Existing_Steps: [], // ← 根节点分支不传递现有步骤
        Baseline_Completion: 0, // ← 从零开始
        stepTaskExisting: currentTask.value,
        goal: generalGoal
      })

      // WebSocket 返回格式: { data: [[action1, action2], [action3, action4]], ... }
      // REST API 返回格式: [[action1, action2], [action3, action4]]
      // 使用通用函数解析 API 响应
      const newAgentActions = parseBranchResponse(response)

      ElMessage.success('任务流程分支创建成功')

      // 创建新的 agent 节点
      if (newAgentActions.length > 0) {
        // 基于同一父节点下的分支数量计算位置
        const currentAgents = currentTask.value?.AgentSelection || []
        const sameParentBranches = selectionStore
          .getTaskProcessBranches(currentTask.value?.Id || '', currentAgents)
          .filter(b => b.parentNodeId === parentNodeId)
        // 新分支的索引 = 现有分支数量（放在最后）
        const newBranchIndex = sameParentBranches.length

        // 根节点位置
        const branchStartX = parentNode.position.x
        // 根节点分支加上固定偏移500，避免和agent分支重叠
        const branchStartY = parentNode.position.y + 200 + 500 + newBranchIndex * 250
        const branchId = String(Date.now())

        // 使用通用函数创建分支节点和边
        const result = createBranchNodesAndEdges(
          newAgentActions,
          branchStartX,
          branchStartY,
          parentNodeId,
          '#67c23a', // 根节点分支颜色
          branchId
        )
        newBranchNodes.push(...result.nodes)
        newBranchEdges.push(...result.edges)

        // 保存分支数据到 store
        if (newBranchNodes.length > 0) {
          const branchTasks = newAgentActions.map(action => ({
            ID: action.id || uuidv4(),
            ActionType: action.type,
            AgentName: action.agent,
            Description: action.description,
            ImportantInput: action.inputs || []
          }))

          saveBranchToStore('root', branchContent, newBranchNodes, newBranchEdges, branchTasks)
        }
      }
    } else {
      // Agent 节点分支
      const parentIsBranchTask = parentNode.data.isBranchTask || false
      const parentOriginalIndex = parentNode.data.originalIndex ?? 0

      // 调用真实 API
      const generalGoal = agentsStore.agentRawPlan.data?.['General Goal'] || ''
      const currentTaskProcess = taskProcess.value || []

      // 根据父节点类型构建 existingSteps
      let existingSteps: any[] = []
      let baselineCompletion = 100

      if (!parentIsBranchTask) {
        // 父节点是主流程节点：传递主流程从 0 到父节点的步骤
        baselineCompletion =
          currentTaskProcess.length > 0
            ? Math.round(((parentOriginalIndex + 1) / currentTaskProcess.length) * 100)
            : 100

        existingSteps = currentTaskProcess.slice(0, parentOriginalIndex + 1).map((p: any) => ({
          ID: p.ID,
          ActionType: p.ActionType,
          AgentName: p.AgentName,
          Description: p.Description,
          ImportantInput: p.ImportantInput || []
        }))
      } else {
        // 父节点是分支节点：从分支数据中获取步骤
        const taskStepId = currentTask.value?.Id || ''
        const currentAgents = currentTask.value?.AgentSelection || []
        const branches = selectionStore.getTaskProcessBranches(taskStepId, currentAgents)

        // 找到父节点所属的分支
        const parentBranch = branches.find(branch => branch.nodes.some(n => n.id === parentNode.id))

        if (parentBranch && parentBranch.tasks) {
          // 获取分支中从第一个节点到父节点的所有步骤
          const parentIndexInBranch = parentBranch.nodes.findIndex(n => n.id === parentNode.id)
          existingSteps = parentBranch.tasks.slice(0, parentIndexInBranch + 1).map((p: any) => ({
            ID: p.ID,
            ActionType: p.ActionType,
            AgentName: p.AgentName,
            Description: p.Description,
            ImportantInput: p.ImportantInput || []
          }))

          // 分支节点的基线完成度：根据主流程进度计算
          baselineCompletion =
            currentTaskProcess.length > 0
              ? Math.round(((parentOriginalIndex + 1) / currentTaskProcess.length) * 100)
              : 100
        }
      }

      const response = await api.branchTaskProcess({
        branch_Number: 1,
        Modification_Requirement: branchContent,
        Existing_Steps: existingSteps,
        Baseline_Completion: baselineCompletion,
        stepTaskExisting: currentTask.value,
        goal: generalGoal
      })

      // 使用通用函数解析 API 响应
      const newAgentActions = parseBranchResponse(response)

      ElMessage.success('任务流程分支创建成功')

      // 创建新的 agent 节点
      if (newAgentActions.length > 0) {
        // 基于同一父节点下的分支数量计算位置
        const currentAgents = currentTask.value?.AgentSelection || []
        const sameParentBranches = selectionStore
          .getTaskProcessBranches(currentTask.value?.Id || '', currentAgents)
          .filter(b => b.parentNodeId === parentNodeId)
        const branchIndex = sameParentBranches.length

        // 计算该父节点在主流程中的位置索引
        let parentNodeIndex = 0
        if (parentNode.data && parentNode.data.originalIndex !== undefined) {
          parentNodeIndex = parentNode.data.originalIndex
        }

        const branchStartX = parentNode.position.x + 200
        // 添加父节点索引的偏移，避免不同父节点的分支重叠
        const branchStartY = parentNode.position.y + 150 + branchIndex * 250 + parentNodeIndex * 300
        const branchId = String(Date.now())

        // 使用通用函数创建分支节点和边
        const result = createBranchNodesAndEdges(
          newAgentActions,
          branchStartX,
          branchStartY,
          parentNodeId,
          '#409eff', // Agent 节点分支颜色
          branchId
        )
        newBranchNodes.push(...result.nodes)
        newBranchEdges.push(...result.edges)

        // 保存分支数据到 store
        if (newBranchNodes.length > 0) {
          const branchTasks = newAgentActions.map(action => ({
            ID: action.id || uuidv4(),
            ActionType: action.type,
            AgentName: action.agent,
            Description: action.description,
            ImportantInput: action.inputs || []
          }))

          saveBranchToStore('task', branchContent, newBranchNodes, newBranchEdges, branchTasks)
        }
      }
    }

    // 重置当前添加分支的节点 ID
    addingBranchNodeId.value = null

    // 适应视图以显示新节点
    nextTick(() => {
      setTimeout(() => {
        fit({ padding: 100, duration: 300 })
      }, 300)
    })
  } catch (error) {
    ElMessage.error('添加分支失败，请重试')
    addingBranchNodeId.value = null
  } finally {
    branchLoading.value = false
  }
}

onConnect(params => addEdges(params))

// 保存任务过程分支到数据库
const saveTaskProcessBranchesToDB = async () => {
  const TaskID = (window as any).__CURRENT_TASK_ID__
  if (TaskID) {
    try {
      await selectionStore.saveTaskProcessBranchesToDB(TaskID)
    } catch (error) {
      console.error('保存任务过程分支数据失败:', error)
    }
  } else {
    console.warn('[saveTaskProcessBranchesToDB] 未找到 TaskID，跳过保存')
  }
}

// 触发自适应视图（供外部调用）
const triggerFitView = () => {
  if (currentTask.value && nodes.value.length > 0) {
    nextTick(() => {
      setTimeout(() => {
        fit({ padding: 0.4, duration: 300 })
      }, 100)
    })
  }
}

// 暴露给父组件
defineExpose({
  triggerFitView
})
</script>

<template>
  <div class="plan-task-container">
    <div v-if="!currentTask || !taskProcess || taskProcess.length === 0" class="empty-state">
      <el-empty description="请选择一个任务过程卡片" />
    </div>

    <div v-else v-loading="branchLoading" class="vue-flow-wrapper">
      <VueFlow
        v-model:nodes="nodes"
        v-model:edges="styledEdges"
        :delete-key-code="null"
        :default-viewport="{ zoom: 0.5, x: 0, y: 0 }"
        :min-zoom="0.2"
        :max-zoom="4"
        @node-click="onNodeClick"
        class="vue-flow-container"
      >
        <template #node-root="nodeProps">
          <div class="root-task-node-wrapper">
            <Handle type="source" :position="Position.Right" id="right" />
            <Handle type="source" :position="Position.Bottom" id="bottom" />

            <!-- 卡片 -->
            <div class="root-node-wrapper is-branch-selected">
              <div class="root-node-content">
                <div class="agent-role">{{ currentTaskContent }}</div>
              </div>
            </div>

            <!-- 底部添加按钮 -->
            <div
              v-if="addingBranchNodeId !== 'root'"
              class="external-add-btn"
              @click.stop="startAddBranch('root')"
            >
              <el-icon :size="12" color="#000000">
                <CirclePlus />
              </el-icon>
            </div>

            <!-- 取消按钮 -->
            <div v-else class="external-add-btn cancel-btn" @click.stop="cancelAddBranch">
              <el-icon :size="12" color="#f56c6c">
                <Remove />
              </el-icon>
            </div>

            <!-- 外部输入框 -->
            <BranchInput
              v-if="addingBranchNodeId === 'root'"
              ref="branchInputRef"
              @submit="submitBranch"
              @cancel="cancelAddBranch"
            />
          </div>
        </template>

        <template #node-agent="nodeProps">
          <div class="task-node-wrapper">
            <!-- 删除按钮 - 仅在可删除的分支节点上显示，在左侧 -->
            <div
              v-if="getNodeDeletable(nodeProps.id).isDeletable"
              class="node-delete-btn left"
              @click.stop="handleDeleteBranch(nodeProps.id)"
            >
              <svg-icon icon-class="close" size="14px" color="#d8d8d8" />
            </div>

            <!-- 删除单个节点按钮 - 非root节点显示，在右上角 -->
            <div
              v-if="nodeProps.id !== 'root'"
              class="node-delete-btn-single"
              @click.stop="handleDeleteNode(nodeProps.id)"
            >
              <svg-icon icon-class="close" size="14px" color="#d8d8d8" />
            </div>

            <div
              class="agent-node-wrapper"
              :class="{ 'is-branch-selected': selectedNodeIds.has(nodeProps.id) }"
            >
              <Handle type="target" :position="Position.Left" id="left" />
              <Handle type="source" :position="Position.Bottom" id="bottom" />
              <div class="agent-node-content">
                <el-tooltip
                  effect="light"
                  placement="bottom"
                  :show-after="1000"
                  popper-class="agent-tooltip-popper"
                >
                  <template #content>
                    <div class="agent-tooltip-content">
                      <div class="agent-tooltip-name">{{ nodeProps.data.agentName }}</div>
                      <div class="agent-tooltip-divider"></div>
                      <div class="agent-tooltip-section">
                        <span class="section-label">职责：</span>
                        <span
                          class="section-value"
                          :style="{ color: nodeProps.data.actionTypeColor }"
                        >
                          {{ nodeProps.data.actionTypeName }}
                        </span>
                      </div>
                      <div class="agent-tooltip-divider"></div>
                      <div class="agent-tooltip-section-title">个人简介</div>
                      <div class="agent-tooltip-profile">{{ nodeProps.data.agentProfile }}</div>
                      <div class="agent-tooltip-divider"></div>
                      <div class="agent-tooltip-section-title">任务描述</div>
                      <div class="agent-tooltip-description">
                        {{ nodeProps.data.agentDescription }}
                      </div>
                    </div>
                  </template>
                  <div class="agent-avatar" :style="{ background: nodeProps.data.agentColor }">
                    <svg-icon :icon-class="nodeProps.data.agentIcon" size="28px" color="#fff" />
                  </div>
                </el-tooltip>
                <div class="agent-name">{{ nodeProps.data.agentName }}</div>
                <div class="agent-role" :style="{ color: nodeProps.data.actionTypeColor }">
                  {{ nodeProps.data.actionTypeName }}
                </div>
              </div>
              <Handle type="source" :position="Position.Right" id="right" />
            </div>

            <!-- 底部添加按钮 -->
            <div
              v-if="addingBranchNodeId !== nodeProps.id"
              class="external-add-btn"
              @click.stop="startAddBranch(nodeProps.id)"
            >
              <el-icon :size="12" color="#000000">
                <CirclePlus />
              </el-icon>
            </div>

            <!-- 取消按钮 -->
            <div v-else class="external-add-btn cancel-btn" @click.stop="cancelAddBranch">
              <el-icon :size="12" color="#f56c6c">
                <Remove />
              </el-icon>
            </div>

            <!-- 外部输入框 -->
            <BranchInput
              v-if="addingBranchNodeId === nodeProps.id"
              ref="branchInputRef"
              @submit="submitBranch"
              @cancel="cancelAddBranch"
            />
          </div>
        </template>
      </VueFlow>

      <!-- 删除分支确认对话框 -->
      <DeleteConfirmDialog
        v-model="deleteDialogVisible"
        title="确认删除该分支 ?"
        content="删除后，该分支无法恢复 !"
        @confirm="confirmDeleteBranch"
      />

      <!-- 删除单个节点确认对话框 -->
      <DeleteConfirmDialog
        v-model="deleteNodeDialogVisible"
        title="确认删除该节点 ?"
        content="删除后，该节点无法恢复 !"
        @confirm="confirmDeleteNode"
      />
    </div>
  </div>
</template>

<style scoped lang="scss">
.plan-task-container {
  width: 100%;
  height: 100%;
}

.vue-flow-wrapper {
  width: 100%;
  height: 100%;
  position: relative;
}

.vue-flow-container {
  width: 100%;
  height: 100%;
}

.empty-state {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
}

.root-node-wrapper {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  min-width: 130px;
  max-width: 180px;
  height: 90px;
  background: var(--color-card-bg-task);
  border-radius: 12px;
  cursor: pointer;
  transition: all 0.2s ease;

  // 始终显示渐变边框
  background: linear-gradient(var(--color-card-bg-task), var(--color-card-bg-task)) padding-box,
    linear-gradient(to right, var(--color-accent), var(--color-accent-secondary)) border-box;
  border: 2px solid transparent;
  box-sizing: border-box;

  &:hover {
    background: linear-gradient(var(--color-card-bg-task-hover), var(--color-card-bg-task-hover))
        padding-box,
      linear-gradient(to right, var(--color-accent), var(--color-accent-secondary)) border-box;
    border: 2px solid transparent;
    box-shadow: var(--color-card-shadow-hover);
  }

  .root-node-content {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 4px;
    max-width: 120px;
    overflow: hidden;
  }

  .agent-name {
    font-size: 13px;
    font-weight: 600;
    color: var(--color-text);
    white-space: nowrap;
    text-align: center;
  }

  .agent-role {
    font-size: 11px;
    font-weight: 500;
    color: var(--color-text-secondary);
    display: -webkit-box;
    -webkit-line-clamp: 3;
    line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
    text-align: center;
  }
}

// 根节点中央按钮
.root-add-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  cursor: pointer;
  transition: all 0.2s ease;

  &:hover {
    transform: scale(1.1);
  }

  &:active {
    transform: scale(0.95);
  }
}

// 根节点包装器（用于容纳外部按钮）
.root-task-node-wrapper {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
}

// 节点包装器（用于容纳外部按钮）
.task-node-wrapper {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
}

// 外部添加按钮
.external-add-btn {
  position: absolute;
  bottom: -5px;
  left: 50%;
  transform: translateX(-50%);
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: all 0.2s ease;
  z-index: 10;
  box-shadow: 0 2px 8px rgba(64, 158, 255, 0.2);

  &:active {
    transform: translateX(-50%) scale(0.95);
  }

  // 取消按钮样式
  &.cancel-btn {
    border-color: #f56c6c;
    box-shadow: 0 2px 8px rgba(245, 108, 108, 0.2);
  }
}

.agent-node-wrapper {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 12px;
  min-width: 130px;
  max-width: 180px;
  height: 90px;
  background-color: var(--color-card-bg-task);
  border: 2px solid var(--color-node-border);
  transition: all 0.2s ease;
  cursor: pointer;

  &:hover {
    background-color: var(--color-card-bg-task-hover);
    border-color: var(--color-node-border);
    box-shadow: var(--color-card-shadow-hover);
  }

  // 分支选中高亮样式（渐变边框）
  &.is-branch-selected {
    background: linear-gradient(var(--color-card-bg-task), var(--color-card-bg-task)) padding-box,
      linear-gradient(to right, var(--color-accent), var(--color-accent-secondary)) border-box;
    border: 2px solid transparent;
    box-sizing: border-box;
    z-index: 10;
  }

  .agent-node-content {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 4px;
  }

  .agent-info {
    display: none;
  }

  .agent-name {
    font-size: 13px;
    font-weight: 600;
    color: var(--color-text);
    white-space: nowrap;
    text-align: center;
  }

  .agent-role {
    font-size: 12px;
    font-weight: 500;
    white-space: nowrap;
    text-align: center;
  }

  .agent-avatar {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    border-radius: 50%;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
    transition: transform 0.2s ease;
    flex-shrink: 0;

    &:hover {
      transform: scale(1.1);
    }
  }
}

:deep(.vue-flow__handle) {
  width: 8px;
  height: 8px;
  background: #43a8aa;
  border: 2px solid #fff;
}

:deep(.vue-flow__edge) {
  .vue-flow__edge-path {
    stroke: #43a8aa;
  }
}

/* 智能体悬浮提示样式 */
:deep(.agent-tooltip-popper) {
  z-index: 4000 !important;
}

.agent-tooltip-content {
  width: 240px;
  max-width: 240px;
}

.agent-tooltip-name {
  font-size: 16px;
  font-weight: bold;
  color: var(--color-text);
  margin-bottom: 4px;
}

.agent-tooltip-divider {
  height: 1px;
  background: #e0e0e0;
  margin: 6px 0;
}

.agent-tooltip-section {
  display: flex;
  align-items: center;
  gap: 4px;
  margin: 4px 0;
  font-size: 14px;
}

.section-label {
  font-weight: 500;
  color: var(--color-text);
}

.section-value {
  font-weight: bold;
}

.agent-tooltip-section-title {
  font-size: 13px;
  font-weight: 600;
  color: var(--color-text);
  margin-top: 4px;
  margin-bottom: 2px;
}

.agent-tooltip-profile {
  font-size: 13px;
  color: var(--color-text);
  line-height: 1.4;
  word-break: break-word;
  margin-bottom: 4px;
}

.agent-tooltip-description {
  font-size: 14px;
  color: var(--color-text);
  line-height: 1.5;
  word-break: break-word;
  margin-top: 4px;
}

// 节点删除按钮
.node-delete-btn {
  position: absolute;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  background-color: #2d2d2d;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: background-color 0.2s ease;
  z-index: 100;

  // 左侧位置
  &.left {
    left: -85px;
    top: 50%;
    transform: translateY(-50%);
  }

  &:hover {
    background-color: #0c0c0c;
  }
}

// 单节点删除按钮（右上角）- 与左侧分支删除按钮样式一致
.node-delete-btn-single {
  position: absolute;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  background-color: #2d2d2d;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: background-color 0.2s ease;
  z-index: 100;
  top: -12px;
  right: -12px;

  &:hover {
    background-color: #0c0c0c;
  }
}

// 边样式 - 与PlanModification.vue保持一致
::deep(.vue-flow__edge.selected .vue-flow__edge-path) {
  stroke: #409eff;
}

::deep(.vue-flow__edge.edge-normal .vue-flow__edge-path) {
  stroke: var(--color-node-border);
  stroke-width: 2;
  stroke-dasharray: 5 5;
}

::deep(.vue-flow__edge.edge-highlighted .vue-flow__edge-path) {
  stroke: var(--color-node-active) !important;
  stroke-width: 2;
  stroke-dasharray: 5 5;
}
</style>

<style>
.agent-tooltip-popper {
  z-index: 4000 !important;
}
</style>
