<script setup lang="ts">
import { computed, onUnmounted, ref, reactive, nextTick, watch, onMounted } from 'vue'
import { throttle } from 'lodash'
import { AnchorLocations, BezierConnector } from '@jsplumb/browser-ui'
import AdditionalOutputCard from './AdditionalOutputCard.vue'
import SvgIcon from '@/components/SvgIcon/index.vue'
import { getActionTypeDisplay, getAgentMapIcon } from '@/layout/components/config.ts'
import { type ConnectArg, Jsplumb } from '@/layout/components/Main/TaskTemplate/utils.ts'
import variables from '@/styles/variables.module.scss'
import { type IRawStepTask, useAgentsStore, type IRawPlanResponse } from '@/stores'
import api, { type StreamingEvent } from '@/api'
import ProcessCard from '../TaskProcess/ProcessCard.vue'
import ExecutePlan from './ExecutePlan.vue'
import websocket from '@/utils/websocket'
import Notification from '@/components/Notification/Notification.vue'
import { useNotification } from '@/composables/useNotification'

const emit = defineEmits<{
  (e: 'refreshLine'): void
  (el: 'setCurrentTask', task: IRawStepTask): void
}>()

const agentsStore = useAgentsStore()
const drawerVisible = ref(false)

const collaborationProcess = computed(() => {
  return agentsStore.agentRawPlan.data?.['Collaboration Process'] ?? []
})

// Step execution status enum
enum StepExecutionStatus {
  WAITING = 'waiting', // Waiting for data
  READY = 'ready', // Ready to execute
  RUNNING = 'running', // Currently running
  COMPLETED = 'completed', // Execution completed
  FAILED = 'failed' // Execution failed
}

// Execution status for each step
const stepExecutionStatus = ref<Record<string, StepExecutionStatus>>({})

// 用于标记暂停时的"最后动作完成"状态
const isPausing = ref(false) // 正在请求暂停（等待当前动作完成）
const isRestarting = ref(false) // 正在重新执行（停止旧执行导致的错误不应显示）

// Check if step is ready to execute (has TaskProcess data)
const isStepReady = (step: IRawStepTask) => {
  return step.TaskProcess && step.TaskProcess.length > 0
}

// 判断动作是否有执行结果
const hasActionResult = (step: IRawStepTask, actionId: string) => {
  const stepResult = agentsStore.executePlan.find(
    r => r.NodeId === step.StepName && r.LogNodeType === 'step'
  )
  if (!stepResult || !stepResult.ActionHistory) {
    return false
  }
  return stepResult.ActionHistory.some(action => action.ID === actionId)
}

// 判断 OutputObject 是否有执行结果
const hasObjectResult = (outputObject?: string) => {
  if (!outputObject) return false
  return agentsStore.executePlan.some(r => r.NodeId === outputObject && r.LogNodeType === 'object')
}

// Get execution status of a step
const getStepStatus = (step: IRawStepTask): StepExecutionStatus => {
  const stepName = step.StepName || step.Id || ''

  // If status is already recorded, return it
  if (stepExecutionStatus.value[stepName]) {
    return stepExecutionStatus.value[stepName]
  }

  // Check if has TaskProcess data
  if (isStepReady(step)) {
    return StepExecutionStatus.READY
  } else {
    return StepExecutionStatus.WAITING
  }
}

// Calculate preparation status of all steps
const stepsReadyStatus = computed(() => {
  const steps = collaborationProcess.value
  const readySteps: string[] = []
  const waitingSteps: string[] = []

  steps.forEach(step => {
    if (isStepReady(step)) {
      readySteps.push(step.StepName || 'Unknown step')
    } else {
      waitingSteps.push(step.StepName || 'Unknown step')
    }
  })

  return {
    ready: readySteps,
    waiting: waitingSteps,
    allReady: waitingSteps.length === 0,
    totalCount: steps.length,
    readyCount: readySteps.length
  }
})

/**
 * 监听步骤数据变化，更新步骤状态并动态追加新步骤
 */
watch(
  () => collaborationProcess.value,
  newSteps => {
    newSteps.forEach(step => {
      const stepId = step.Id || step.StepName || ''
      const stepName = step.StepName || step.Id || ''
      const currentStatus = stepExecutionStatus.value[stepName]

      if (isStepReady(step)) {
        // 步骤数据已就绪，更新状态
        if (!currentStatus || currentStatus === StepExecutionStatus.WAITING) {
          stepExecutionStatus.value[stepName] = StepExecutionStatus.READY
        }

        // 动态追加新步骤到执行队列
        if (loading.value && isStreaming.value && currentExecutionId.value) {
          if (!sentStepIds.value.has(stepId)) {
            console.log(`🔄 Watch监听到新就绪步骤: ${stepName}, 准备追加到执行队列`)
            console.log(`   - loading: ${loading.value}`)
            console.log(`   - isStreaming: ${isStreaming.value}`)
            console.log(`   - currentExecutionId: ${currentExecutionId.value}`)

            sentStepIds.value.add(stepId)

            // 异步追加步骤到后端执行队列
            api
              .addStepsToExecution(currentExecutionId.value, [step])
              .then(addedCount => {
                if (addedCount > 0) {
                  console.log(`✅ 成功追加步骤: ${stepName}`)

                  // 更新总步骤数显示
                  const totalStepsCount = collaborationProcess.value.length
                  const currentStep = executionProgress.value.currentStep || 1
                  executionProgress.value.totalSteps = totalStepsCount
                } else {
                  console.warn(`⚠️ 追加步骤失败: ${stepName} - 执行ID不存在或已结束`)
                  // 追加失败，移除标记以便重试
                  sentStepIds.value.delete(stepId)
                }
              })
              .catch(error => {
                console.error(`❌ 追加步骤失败: ${stepName}`, error)
                // 追加失败，移除标记以便重试
                sentStepIds.value.delete(stepId)
              })
          }
        } else if (loading.value && !isStreaming.value) {
          console.log(`⚠️ 步骤 ${stepName} 已就绪，但尚未开始流式传输`)
        } else if (loading.value && isStreaming.value && !currentExecutionId.value) {
          console.log(`⚠️ 步骤 ${stepName} 已就绪，但currentExecutionId为空`)
        }
      } else {
        // 步骤未就绪，设置为WAITING
        if (!currentStatus) {
          stepExecutionStatus.value[stepName] = StepExecutionStatus.WAITING
        }
      }
    })
  },
  { deep: true }
)

// Watch additional outputs changes
watch(
  () => agentsStore.additionalOutputs,
  () => {
    nextTick(() => {
      setTimeout(() => {
        jsplumb.repaintEverything()
      }, 0)
    })
  },
  { deep: true }
)

// Edit logic
const editMode = ref(false)
const editMap = reactive<Record<string, boolean>>({})
const editBuffer = reactive<Record<string, string | undefined>>({})
const showPopover = ref(false)
function getProcessDescription(stepId: string, processId: string) {
  const step = collaborationProcess.value.find(s => s.Id === stepId)
  if (step) {
    const process = step.TaskProcess.find(p => p.ID === processId)
    return process?.Description || ''
  }
  return ''
}

function handleOpenEdit(stepId: string, processId: string) {
  if (!editMode.value) return
  const key = `${stepId}-${processId}`
  editMap[key] = true
  editBuffer[key] = getProcessDescription(stepId, processId)
}

function handleSaveEdit(stepId: string, processId: string, value: string) {
  const key = `${stepId}-${processId}`
  const step = collaborationProcess.value.find(s => s.Id === stepId)
  if (step) {
    const process = step.TaskProcess.find(p => p.ID === processId)
    if (process) {
      // 保存旧值用于比较
      const oldValue = process.Description

      // 只有内容真正变化时才更新和记录修改
      if (value !== oldValue) {
        process.Description = value
        // 记录修改过的步骤索引到 store
        const stepIndex = collaborationProcess.value.findIndex(s => s.Id === stepId)
        if (stepIndex >= 0) {
          agentsStore.addModifiedStep(stepIndex)
          console.log(
            `📝 步骤 ${stepIndex + 1} (${step.StepName}) 的描述已被修改，将从该步骤重新执行`
          )
        }
      } else {
        console.log(`ℹ️ 步骤 ${step.StepName} 的描述未发生变化，不记录修改`)
      }
    }
  }
  editMap[key] = false
}
const jsplumb = new Jsplumb('task-results-main', {
  connector: {
    type: BezierConnector.type,
    options: { curviness: 30, stub: 10 }
  }
})

// Refresh connections in real-time when collapsing panels
let timer: ReturnType<typeof setInterval> | null = null
function handleCollapse() {
  if (timer) {
    clearInterval(timer)
  }
  timer = setInterval(() => {
    jsplumb.repaintEverything()
    emit('refreshLine')
  }, 1) as ReturnType<typeof setInterval>

  // Default fully open after 3 seconds
  const timer1 = setTimeout(() => {
    if (timer) {
      clearInterval(timer)
      timer = null
    }
  }, 3000)

  onUnmounted(() => {
    if (timer) {
      clearInterval(timer)
    }
    if (timer1) {
      clearInterval(timer1)
    }
  })
}

// Create internal connections
function createInternalLine(id?: string) {
  const arr: ConnectArg[] = []
  jsplumb.reset()
  collaborationProcess.value.forEach(item => {
    // 创建左侧流程与产出的连线
    arr.push({
      sourceId: `task-results-${item.Id}-0`,
      targetId: `task-results-${item.Id}-1`,
      anchor: [AnchorLocations.Left, AnchorLocations.Left]
    })
    collaborationProcess.value.forEach(jitem => {
      // 创建左侧产出与上一步流程的连线
      if (item.InputObject_List!.includes(jitem.OutputObject ?? '')) {
        arr.push({
          sourceId: `task-results-${jitem.Id}-1`,
          targetId: `task-results-${item.Id}-0`,
          anchor: [AnchorLocations.Left, AnchorLocations.Left],
          config: {
            type: 'output'
          }
        })
      }
      // 创建右侧任务程序与InputObject字段的连线
      jitem.TaskProcess.forEach(i => {
        if (i.ImportantInput?.includes(`InputObject:${item.OutputObject}`)) {
          const color = getActionTypeDisplay(i.ActionType)?.color ?? ''
          const sourceId = `task-results-${item.Id}-1`
          const targetId = `task-results-${jitem.Id}-0-${i.ID}`
          arr.push({
            sourceId,
            targetId,
            anchor: [AnchorLocations.Right, AnchorLocations.Right],
            config: {
              stops: [
                [0, color],
                [1, color]
              ],
              transparent: targetId !== id
            }
          })
        }
      })
    })

    // 创建右侧TaskProcess内部连线
    item.TaskProcess?.forEach(i => {
      if (!i.ImportantInput?.length) {
        return
      }
      item.TaskProcess?.forEach(i2 => {
        if (i.ImportantInput.includes(`ActionResult:${i2.ID}`)) {
          const color = getActionTypeDisplay(i.ActionType)?.color ?? ''
          const sourceId = `task-results-${item.Id}-0-${i2.ID}`
          const targetId = `task-results-${item.Id}-0-${i.ID}`
          arr.push({
            sourceId,
            targetId,
            anchor: [AnchorLocations.Right, AnchorLocations.Right],
            config: {
              stops: [
                [0, color],
                [1, color]
              ],
              transparent: targetId !== id
            }
          })
        }
      })
    })
  })

  jsplumb.connects(arr)
  jsplumb.repaintEverything()
}

const loading = ref(false)
const executionProgress = ref({
  currentStep: 0,
  totalSteps: 0,
  currentAction: 0,
  totalActions: 0,
  currentStepName: ''
})

// Notification system
const {
  notifications,
  progress: showProgress,
  updateProgressDetail,
  updateNotificationTitle,
  success,
  info,
  warning,
  error
} = useNotification()
const currentProgressNotificationId = ref<string | null>(null)
const currentProgressTitle = ref('任务执行中') // 🆕 追踪当前进度通知的标题

/**
 * 更新进度通知的标题
 */
function updateProgressNotificationTitle(title: string) {
  currentProgressTitle.value = title
  if (currentProgressNotificationId.value) {
    // 直接更新通知的主标题
    updateNotificationTitle(currentProgressNotificationId.value, title)
  }
}

// Pause functionality state
const isPaused = ref(false)
const isStreaming = ref(false)
const isButtonLoading = ref(false)

// Dynamic execution state
const currentExecutionId = ref<string | null>(null)
const sentStepIds = ref<Set<string>>(new Set())

// Flag to prevent duplicate execution calls
const isExecutingNextBatch = ref(false)

/**
 * 执行下一批已就绪的步骤（使用动态追加模式）
 * 支持在执行过程中动态追加新步骤
 */
async function executeNextReadyBatch() {
  if (isExecutingNextBatch.value) {
    console.log('executeNextReadyBatch already running, skipping duplicate call')
    return
  }

  isExecutingNextBatch.value = true

  try {
    const steps = collaborationProcess.value

    // 收集所有已就绪但未执行的步骤
    const readySteps: IRawStepTask[] = []

    for (let i = 0; i < steps.length; i++) {
      const step = steps[i]
      if (!step) continue

      const stepId = step.Id || step.StepName || ''
      const stepName = step.StepName || step.Id || ''

      // 调试日志
      const isReady = isStepReady(step)
      const wasSent = sentStepIds.value.has(stepId)
      const status = stepExecutionStatus.value[stepId]

      console.log(
        `[步骤检查] ${stepName}: isReady=${isReady}, wasSent=${wasSent}, status=${status}`
      )

      // 只收集未发送的已就绪步骤
      if (isStepReady(step) && !sentStepIds.value.has(stepId)) {
        if (!status || status === StepExecutionStatus.READY) {
          readySteps.push(step)
          sentStepIds.value.add(stepId)
          console.log(`✅ 收集步骤: ${stepName}, 当前总数: ${readySteps.length}`)
        }
      }
    }

    console.log(`📊 总共收集到 ${readySteps.length} 个已就绪步骤`)

    if (readySteps.length > 0) {
      // 如果还没有executionId，生成一个
      if (!currentExecutionId.value) {
        const generalGoal = agentsStore.agentRawPlan.data?.['General Goal'] || ''
        const timestamp = Date.now()
        currentExecutionId.value = `${generalGoal.replace(/\s+/g, '_')}_${timestamp}`
        console.log('🆔 生成执行ID:', currentExecutionId.value)
      }

      try {
        // 标记所有要执行的步骤为运行中
        readySteps.forEach(step => {
          const stepName = step.StepName || step.Id || ''
          stepExecutionStatus.value[stepName] = StepExecutionStatus.RUNNING
        })

        // 构建批量执行计划
        const batchPlan: IRawPlanResponse = {
          'General Goal': agentsStore.agentRawPlan.data?.['General Goal'] || '',
          'Initial Input Object': agentsStore.agentRawPlan.data?.['Initial Input Object'] || [],
          'Collaboration Process': readySteps
        }

        // 执行批量步骤（启用动态追加模式）
        await new Promise<void>((resolve, reject) => {
          api.executePlanOptimized(
            batchPlan,
            // onMessage: 处理每个事件
            (event: StreamingEvent) => {
              // 当后端开始返回数据时，设置isStreaming
              if (!isStreaming.value) {
                isStreaming.value = true
              }

              // 如果正在暂停（isPausing）或已暂停（isPaused），只允许特定事件
              // 这样可以确保当前正在完成的动作的结果能够被正确保存
              if (isPausing.value || isPaused.value) {
                if (
                  event.type !== 'action_complete' &&
                  event.type !== 'step_complete' &&
                  event.type !== 'error'
                ) {
                  return
                }
              }

              switch (event.type) {
                case 'step_start':
                  // 使用全局步骤索引计算当前步骤
                  const globalStepIndex = collaborationProcess.value.findIndex(
                    s => s.StepName === event.step_name
                  )
                  executionProgress.value = {
                    currentStep:
                      globalStepIndex >= 0 ? globalStepIndex + 1 : (event.step_index || 0) + 1,
                    totalSteps: collaborationProcess.value.length,
                    currentAction: 0,
                    totalActions: 0,
                    currentStepName: event.step_name
                  }

                  // 🆕 创建或更新进度通知，显示详细步骤信息（根据状态显示不同标题）
                  const currentTitle = isPausing.value ? '暂停中' : '任务执行中'
                  updateProgressNotificationTitle(currentTitle)

                  if (!currentProgressNotificationId.value) {
                    currentProgressNotificationId.value = showProgress(
                      currentTitle,
                      executionProgress.value.currentStep,
                      executionProgress.value.totalSteps
                    )
                    updateProgressDetail(
                      currentProgressNotificationId.value,
                      `步骤 ${executionProgress.value.currentStep}/${executionProgress.value.totalSteps}`,
                      `正在执行: ${event.step_name}`
                    )
                  } else {
                    updateProgressDetail(
                      currentProgressNotificationId.value,
                      `步骤 ${executionProgress.value.currentStep}/${executionProgress.value.totalSteps}`,
                      `正在执行: ${event.step_name}`,
                      executionProgress.value.currentStep,
                      executionProgress.value.totalSteps
                    )
                  }
                  break

                case 'action_complete':
                  const parallelInfo = event.batch_info?.is_parallel
                    ? ` [并行 ${event.batch_info!.batch_size} 个动作]`
                    : ''

                  // 使用全局步骤索引
                  const globalStepIndexForAction = collaborationProcess.value.findIndex(
                    s => s.StepName === event.step_name
                  )
                  const stepIndexForAction =
                    globalStepIndexForAction >= 0
                      ? globalStepIndexForAction + 1
                      : (event.step_index || 0) + 1
                  const totalStepsValue = collaborationProcess.value.length

                  executionProgress.value = {
                    ...executionProgress.value,
                    currentAction: event.completed_actions,
                    totalActions: event.total_actions
                  }

                  // 检测是否正在暂停（等待当前动作完成）
                  if (isPausing.value) {
                    // 当前动作完成，完成暂停
                    isPaused.value = true
                    isPausing.value = false
                    // 🆕 更新进度通知标题为"已暂停..."
                    updateProgressNotificationTitle('已暂停')
                    // 只显示简短的成功提示，不覆盖进度通知
                    console.log('✅ 已暂停执行')
                  }

                  // 更新详细进度信息，显示动作级别进度
                  if (currentProgressNotificationId.value) {
                    updateProgressDetail(
                      currentProgressNotificationId.value,
                      `步骤 ${stepIndexForAction}/${totalStepsValue}`,
                      `${event.step_name} - 动作 ${event.completed_actions}/${event.total_actions} 完成${parallelInfo}`,
                      stepIndexForAction,
                      totalStepsValue
                    )
                  }

                  // 实时更新store
                  const existingStep = collaborationProcess.value.find(
                    s => s.StepName === event.step_name
                  )
                  if (existingStep) {
                    const currentResults = agentsStore.executePlan
                    const stepLogNode = currentResults.find(
                      r => r.NodeId === event.step_name && r.LogNodeType === 'step'
                    )
                    if (!stepLogNode) {
                      const newStepLog = {
                        LogNodeType: 'step',
                        NodeId: event.step_name,
                        InputName_List: existingStep.InputObject_List || [],
                        OutputName: existingStep.OutputObject || '',
                        chatLog: [],
                        inputObject_Record: [],
                        ActionHistory: [event.action_result]
                      }
                      agentsStore.setExecutePlan([...currentResults, newStepLog])
                    } else {
                      stepLogNode.ActionHistory.push(event.action_result)
                      agentsStore.setExecutePlan([...currentResults])
                    }
                  }
                  break

                case 'step_complete':
                  stepExecutionStatus.value[event.step_name] = StepExecutionStatus.COMPLETED

                  // 更新完整步骤日志
                  const currentResults = agentsStore.executePlan
                  const existingLog = currentResults.find(
                    r => r.NodeId === event.step_name && r.LogNodeType === 'step'
                  )
                  if (existingLog) {
                    existingLog.ActionHistory = event.step_log_node.ActionHistory
                    agentsStore.setExecutePlan([...currentResults])
                  } else if (event.step_log_node) {
                    agentsStore.setExecutePlan([...currentResults, event.step_log_node])
                  }
                  // 添加object_log_node
                  const updatedResults = agentsStore.executePlan
                  if (event.object_log_node) {
                    agentsStore.setExecutePlan([...updatedResults, event.object_log_node])
                  }
                  break

                case 'execution_complete':
                  readySteps.forEach(step => {
                    const stepName = step.StepName || step.Id || ''
                    if (stepExecutionStatus.value[stepName] !== StepExecutionStatus.COMPLETED) {
                      stepExecutionStatus.value[stepName] = StepExecutionStatus.COMPLETED
                    }
                  })

                  // 🆕 关闭进度通知并显示完成通知
                  if (currentProgressNotificationId.value) {
                    removeNotification(currentProgressNotificationId.value)
                    currentProgressNotificationId.value = null
                  }
                  // 重置标题
                  currentProgressTitle.value = '任务执行中'

                  success('任务执行完成', `所有步骤已执行完成`, { duration: 3000 })
                  resolve()
                  break

                case 'error':
                  const errorMessage = event.message || event.error || '未知错误'
                  console.error('执行错误:', errorMessage)

                  // 如果正在重新执行，不显示错误通知（因为旧执行的步骤中断是预期的）
                  if (isRestarting.value) {
                    console.log('ℹ️  正在重新执行，忽略旧执行的中断错误')
                    resolve() // 正常完成，不显示错误
                    return
                  }

                  // 关闭进度通知并显示错误通知
                  if (currentProgressNotificationId.value) {
                    removeNotification(currentProgressNotificationId.value)
                    currentProgressNotificationId.value = null
                  }

                  error('执行错误', errorMessage, { duration: 5000 })

                  readySteps.forEach(step => {
                    const stepName = step.StepName || step.Id || ''
                    stepExecutionStatus.value[stepName] = StepExecutionStatus.FAILED
                  })
                  reject(new Error(errorMessage))
                  break
              }
            },
            // onError: 处理错误
            (err: Error) => {
              console.error('流式执行错误:', err)

              // 如果正在重新执行，不显示错误通知（因为旧执行的步骤中断是预期的）
              if (isRestarting.value) {
                console.log('ℹ️  正在重新执行，忽略旧执行的中断错误')
                resolve() // 正常完成，不显示错误
                return
              }

              // 关闭进度通知并显示错误通知
              if (currentProgressNotificationId.value) {
                removeNotification(currentProgressNotificationId.value)
                currentProgressNotificationId.value = null
              }

              error('执行失败', err.message, { duration: 5000 })

              readySteps.forEach(step => {
                const stepName = step.StepName || step.Id || ''
                stepExecutionStatus.value[stepName] = StepExecutionStatus.FAILED
              })
              reject(err)
            },
            // onComplete: 完成回调
            () => {
              // 关闭进度通知
              if (currentProgressNotificationId.value) {
                removeNotification(currentProgressNotificationId.value)
                currentProgressNotificationId.value = null
              }
              resolve()
            },
            // useWebSocket: 使用WebSocket
            true,
            // existingKeyObjects: 已存在的KeyObjects
            {},
            // enableDynamic: 启用动态追加模式
            true,
            // onExecutionStarted: 接收执行ID
            (executionId: string) => {
              console.log('动态执行已启动，执行ID:', executionId)
            },
            // executionId: 前端生成的执行ID
            currentExecutionId.value || undefined
          )
        })

        // 不再递归调用，而是通过watch监听追加新步骤
      } catch (err) {
        error('执行失败', '批量执行失败')
        loading.value = false
        isPaused.value = false
        isStreaming.value = false
      }
    } else {
      // 没有更多已就绪的步骤
      loading.value = false
      isPaused.value = false
      isStreaming.value = false

      // 检查是否还有等待填充的步骤
      const hasWaitingSteps = steps.some(step => step && !isStepReady(step))

      if (hasWaitingSteps) {
        const waitingStepNames = steps
          .filter(step => step && !isStepReady(step))
          .map(step => step?.StepName || '未知')
        info('等待数据填充', `等待 ${waitingStepNames.length} 个步骤数据填充中...`)
      } else {
        success('执行完成', '所有步骤已完成')
      }
    }
  } finally {
    isExecutingNextBatch.value = false
  }
}

/**
 * 移除通知
 */
function removeNotification(id: string) {
  const index = notifications.value.findIndex(n => n.id === id)
  if (index !== -1) {
    notifications.value.splice(index, 1)
  }
}

// Pause/Resume handler
async function handlePauseResume() {
  if (isPaused.value) {
    // Resume execution - 检查是否有修改的步骤
    if (agentsStore.hasModifiedSteps()) {
      // 有修改的步骤，必须从最早修改的步骤重新执行
      // 因为步骤之间是串行依赖的，修改了步骤2会导致步骤2-6都需要重新执行
      const earliestModifiedIndex = Math.min(...agentsStore.modifiedSteps)
      const modifiedStepName =
        collaborationProcess.value[earliestModifiedIndex]?.StepName ||
        `步骤${earliestModifiedIndex + 1}`

      console.log(`🔄 从步骤 ${earliestModifiedIndex + 1} (${modifiedStepName}) 重新执行`)
      success('开始重新执行', `检测到步骤修改，从步骤 ${earliestModifiedIndex + 1} 重新执行`)

      // 直接调用重新执行函数
      await restartFromStep(earliestModifiedIndex)

      return
    }

    // 正常恢复执行（没有修改）
    try {
      if (websocket.connected) {
        await websocket.send('resume_execution', {
          goal: agentsStore.agentRawPlan.data?.['General Goal'] || ''
        })
        // 只有在收到成功响应后才更新状态
        isPaused.value = false
        isPausing.value = false
        // 🆕 恢复执行时更新进度通知标题
        updateProgressNotificationTitle('任务执行中')
        success('已恢复', '已恢复执行')
      } else {
        warning('无法恢复', 'WebSocket未连接，无法恢复执行')
      }
    } catch (error) {
      error('恢复失败', '恢复执行失败')
      // 恢复失败时，保持原状态不变（仍然是暂停状态）
    }
  } else {
    // Pause execution
    try {
      if (websocket.connected) {
        // 先设置 isPausing，允许接收当前正在执行的动作的结果
        isPausing.value = true
        info('暂停中', '正在等待当前动作完成')

        await websocket.send('pause_execution', {
          goal: agentsStore.agentRawPlan.data?.['General Goal'] || ''
        })

        // 注意：不立即设置 isPaused = true
        // 而是等待当前动作完成后，在 action_complete 事件中设置
        // 这样可以确保在动作真正完成后才显示"已暂停"
      } else {
        warning('无法暂停', 'WebSocket未连接，无法暂停')
        isPausing.value = false
      }
    } catch (error) {
      error('暂停失败', '暂停执行失败')
      // 暂停失败时，重置状态
      isPausing.value = false
    }
  }
}

// ==================== 重新执行功能 ====================

/**
 * 从RehearsalLog中提取KeyObjects
 * @param rehearsalLog RehearsalLog数组
 * @returns KeyObjects字典
 */
function buildKeyObjectsFromLog(rehearsalLog: any[]): Record<string, any> {
  const keyObjects: Record<string, any> = {}

  for (const logNode of rehearsalLog) {
    if (logNode.LogNodeType === 'object' && logNode.content) {
      keyObjects[logNode.NodeId] = logNode.content
    }
  }

  return keyObjects
}

/**
 * 构建截断后的 RehearsalLog（使用步骤名称匹配）
 * @param restartFromStepIndex 重新执行的起始步骤索引（例如：1 表示从步骤2重新执行）
 * @returns 截断后的 RehearsalLog
 */
function buildTruncatedRehearsalLog(restartFromStepIndex: number) {
  const steps = agentsStore.agentRawPlan.data?.['Collaboration Process'] || []
  const truncatedLog: any[] = []

  for (const logNode of agentsStore.executePlan) {
    if (logNode.LogNodeType === 'step') {
      const stepIndex = steps.findIndex((s: any) => s.StepName === logNode.NodeId)
      if (stepIndex >= 0 && stepIndex < restartFromStepIndex) {
        truncatedLog.push(logNode)
      }
    } else if (logNode.LogNodeType === 'object') {
      const stepIndex = steps.findIndex((s: any) => s.OutputObject === logNode.NodeId)
      if (stepIndex >= 0 && stepIndex < restartFromStepIndex) {
        truncatedLog.push(logNode)
      }
    }
  }

  return truncatedLog
}

/**
 * 清除执行结果中指定步骤及之后的记录
 * @param fromStepIndex 起始步骤索引
 */
function clearExecutionResults(fromStepIndex: number) {
  const steps = agentsStore.agentRawPlan.data?.['Collaboration Process'] || []

  // 过滤掉要重新执行的步骤及其之后的所有步骤
  agentsStore.executePlan = agentsStore.executePlan.filter(logNode => {
    if (logNode.LogNodeType === 'step') {
      // 找到该步骤在原始步骤列表中的索引
      const stepIndex = steps.findIndex((s: any) => s.StepName === logNode.NodeId)
      return stepIndex < fromStepIndex
    }
    // 对于 object 节点，也需要判断
    if (logNode.LogNodeType === 'object') {
      // 找到该 object 对应的步骤索引
      const stepIndex = steps.findIndex((s: any) => s.OutputObject === logNode.NodeId)
      return stepIndex < fromStepIndex
    }
    return true
  })
}

/**
 * 重置步骤执行状态
 * @param fromStepIndex 起始步骤索引
 */
function resetStepStatus(fromStepIndex: number) {
  const steps = agentsStore.agentRawPlan.data?.['Collaboration Process'] || []

  for (let i = fromStepIndex; i < steps.length; i++) {
    const step = steps[i]
    if (!step) continue
    const stepName = step.StepName || step.Id || ''
    stepExecutionStatus.value[stepName] = StepExecutionStatus.READY
  }
}

/**
 * 从指定步骤重新执行
 * @param stepIndex 要重新执行的步骤索引（例如：1 表示从步骤2重新执行）
 */
async function restartFromStep(stepIndex: number) {
  try {
    loading.value = true
    isRestarting.value = true // 标记正在重新执行

    // 清空修改记录（避免重复执行）
    agentsStore.clearModifiedSteps()

    // 0. 先停止旧的执行（避免双重执行）
    if (websocket.connected && currentExecutionId.value) {
      try {
        console.log('🛑 停止旧的执行任务，避免双重执行')
        const stopResponse = await websocket.send('stop_execution', {
          goal: agentsStore.agentRawPlan.data?.['General Goal'] || ''
        })
        console.log('✅ 后端确认停止:', stopResponse)
        // 等待一下确保后端完全停止
        await new Promise(resolve => setTimeout(resolve, 1000))
      } catch (err) {
        console.warn('⚠️ 停止旧执行失败（可能已经停止）:', err)
      }
    }

    // 1. 构建截断后的 RehearsalLog
    const truncatedLog = buildTruncatedRehearsalLog(stepIndex)

    // 2. 从截断日志中提取 KeyObjects
    const existingKeyObjects = buildKeyObjectsFromLog(truncatedLog)

    console.log('📦 传递给后端的数据:', {
      truncatedLogLength: truncatedLog.length,
      keyObjectsCount: Object.keys(existingKeyObjects).length,
      keyObjectsKeys: Object.keys(existingKeyObjects)
    })

    // 3. 清除前端执行结果中指定步骤及之后的记录
    clearExecutionResults(stepIndex)

    // 3.5 关闭旧的进度通知（避免通知混乱）
    if (currentProgressNotificationId.value) {
      removeNotification(currentProgressNotificationId.value)
      currentProgressNotificationId.value = null
    }

    // 4. 重置步骤状态
    resetStepStatus(stepIndex)

    // 4.5 强制触发 Vue 响应式更新
    nextTick(() => {
      // 触发 UI 更新
    })

    // 5. 重置执行状态为执行中
    isPaused.value = false
    isStreaming.value = true
    loading.value = true

    // 6. 调用执行 API，传递截断后的 RehearsalLog 和 KeyObjects
    api.executePlanOptimized(
      agentsStore.agentRawPlan.data!,
      // onMessage - 使用内联函数处理事件
      (event: StreamingEvent) => {
        // 如果正在暂停（isPausing）或已暂停（isPaused），只允许特定事件
        // 这样可以确保当前正在完成的动作的结果能够被正确保存
        if (isPausing.value || isPaused.value) {
          if (
            event.type !== 'action_complete' &&
            event.type !== 'step_complete' &&
            event.type !== 'error'
          ) {
            return
          }
        }

        switch (event.type) {
          case 'step_start':
            stepExecutionStatus.value[event.step_name] = StepExecutionStatus.RUNNING

            // 使用全局步骤索引计算当前步骤
            const globalStepIndex = collaborationProcess.value.findIndex(
              s => s.StepName === event.step_name
            )
            const currentStepNumber =
              globalStepIndex >= 0 ? globalStepIndex + 1 : (event.step_index || 0) + 1

            // 🆕 创建或更新进度通知（根据状态显示不同标题）
            const restartTitle = isPausing.value ? '暂停中' : '重新执行中'
            updateProgressNotificationTitle(restartTitle)

            if (!currentProgressNotificationId.value) {
              currentProgressNotificationId.value = showProgress(
                restartTitle,
                currentStepNumber,
                collaborationProcess.value.length
              )
              updateProgressDetail(
                currentProgressNotificationId.value,
                `步骤 ${currentStepNumber}/${collaborationProcess.value.length}`,
                `正在执行: ${event.step_name}`
              )
            } else {
              updateProgressDetail(
                currentProgressNotificationId.value,
                `步骤 ${currentStepNumber}/${collaborationProcess.value.length}`,
                `正在执行: ${event.step_name}`,
                currentStepNumber,
                collaborationProcess.value.length
              )
            }
            break

          case 'action_complete':
            // 检测是否正在暂停（等待当前动作完成）
            if (isPausing.value) {
              // 当前动作完成，完成暂停
              isPaused.value = true
              isPausing.value = false
              // 🆕 更新进度通知标题为"已暂停..."
              updateProgressNotificationTitle('已暂停')
              console.log('✅ 已暂停执行')
            }

            // 实时更新store
            const existingStep = collaborationProcess.value.find(
              s => s.StepName === event.step_name
            )
            if (existingStep) {
              const currentResults = agentsStore.executePlan
              const stepLogNode = currentResults.find(
                r => r.NodeId === event.step_name && r.LogNodeType === 'step'
              )
              if (!stepLogNode) {
                const newStepLog = {
                  LogNodeType: 'step',
                  NodeId: event.step_name,
                  InputName_List: existingStep.InputObject_List || [],
                  OutputName: existingStep.OutputObject || '',
                  chatLog: [],
                  inputObject_Record: [],
                  ActionHistory: [event.action_result]
                }
                agentsStore.setExecutePlan([...currentResults, newStepLog])
              } else {
                stepLogNode.ActionHistory.push(event.action_result)
                agentsStore.setExecutePlan([...currentResults])
              }
            }

            // 使用全局步骤索引
            const globalStepIndexForAction = collaborationProcess.value.findIndex(
              s => s.StepName === event.step_name
            )
            const stepNumberForAction =
              globalStepIndexForAction >= 0
                ? globalStepIndexForAction + 1
                : (event.step_index || 0) + 1

            // 更新进度通知
            if (currentProgressNotificationId.value) {
              const parallelInfo = event.batch_info?.is_parallel
                ? ` [并行 ${event.batch_info!.batch_size} 个动作]`
                : ''

              updateProgressDetail(
                currentProgressNotificationId.value,
                `步骤 ${stepNumberForAction}/${collaborationProcess.value.length}`,
                `${event.step_name} - 动作 ${event.completed_actions}/${event.total_actions} 完成${parallelInfo}`,
                stepNumberForAction,
                collaborationProcess.value.length
              )
            }
            break

          case 'step_complete':
            stepExecutionStatus.value[event.step_name] = StepExecutionStatus.COMPLETED

            // 更新完整步骤日志
            const currentResults = agentsStore.executePlan
            const existingLog = currentResults.find(
              r => r.NodeId === event.step_name && r.LogNodeType === 'step'
            )
            if (existingLog) {
              existingLog.ActionHistory = event.step_log_node.ActionHistory
              agentsStore.setExecutePlan([...currentResults])
            } else if (event.step_log_node) {
              agentsStore.setExecutePlan([...currentResults, event.step_log_node])
            }
            // 添加object_log_node
            const updatedResults = agentsStore.executePlan
            if (event.object_log_node) {
              agentsStore.setExecutePlan([...updatedResults, event.object_log_node])
            }
            break

          case 'execution_complete':
            const steps = collaborationProcess.value
            steps.forEach(step => {
              const stepName = step.StepName || step.Id || ''
              if (stepExecutionStatus.value[stepName] !== StepExecutionStatus.COMPLETED) {
                stepExecutionStatus.value[stepName] = StepExecutionStatus.COMPLETED
              }
            })

            // 关闭进度通知并显示完成通知
            if (currentProgressNotificationId.value) {
              removeNotification(currentProgressNotificationId.value)
              currentProgressNotificationId.value = null
            }

            success('重新执行完成', `所有步骤已执行完成`, { duration: 3000 })
            loading.value = false
            isPaused.value = false
            isStreaming.value = false
            break

          case 'error':
            const errorMessage = event.message || '未知错误'
            console.error('重新执行错误:', errorMessage)

            // 关闭进度通知
            if (currentProgressNotificationId.value) {
              removeNotification(currentProgressNotificationId.value)
              currentProgressNotificationId.value = null
            }

            // 静默处理所有错误，不显示任何通知
            loading.value = false
            isPaused.value = false
            isStreaming.value = false
            isRestarting.value = false // 重新执行结束
            break
        }
      },
      // onError
      (err: Error) => {
        console.error('重新执行错误:', err)

        // 关闭进度通知
        if (currentProgressNotificationId.value) {
          removeNotification(currentProgressNotificationId.value)
          currentProgressNotificationId.value = null
        }

        // 静默处理所有错误，不显示任何通知
        loading.value = false
        isPaused.value = false
        isStreaming.value = false
        isRestarting.value = false // 重新执行结束
      },
      // onComplete
      () => {
        // 关闭进度通知
        if (currentProgressNotificationId.value) {
          removeNotification(currentProgressNotificationId.value)
          currentProgressNotificationId.value = null
        }

        loading.value = false
        isPaused.value = false
        isStreaming.value = false
        isRestarting.value = false // 重新执行结束
      },
      true, // useWebSocket
      existingKeyObjects, // ✅ 传递从截断日志中提取的KeyObjects
      true, // enableDynamic
      (executionId: string) => {
        currentExecutionId.value = executionId
      },
      undefined, // executionId
      stepIndex, // restartFromStepIndex
      truncatedLog // ✅ 传递截断后的 RehearsalLog
    )

    success('重新执行', `正在从步骤 ${stepIndex + 1} 重新执行...`)
  } catch (err) {
    console.error('重新执行失败:', err)
    error('重新执行失败', '无法启动重新执行')
    loading.value = false
    isRestarting.value = false // 重新执行失败，也要重置标记
  }
}

// Handle execute button click
async function handleExecuteButtonClick() {
  // If streaming, show pause/resume functionality
  if (isStreaming.value) {
    await handlePauseResume()
    return
  }

  // Otherwise, execute normal task execution logic
  await handleRun()
}

async function handleRun() {
  // Check if there are ready steps
  const readySteps = stepsReadyStatus.value.ready
  const waitingSteps = stepsReadyStatus.value.waiting

  if (readySteps.length === 0 && waitingSteps.length > 0) {
    warning(
      '步骤数据未就绪',
      `${waitingSteps.length} 个步骤的数据还在填充中：${waitingSteps.join(
        '、'
      )}。建议等待数据填充完成后再执行。`,
      { duration: 5000 }
    )
    return
  }

  // Set button brief loading state (prevent double-click)
  isButtonLoading.value = true
  setTimeout(() => {
    isButtonLoading.value = false
  }, 1000)

  // Reset pause and streaming state
  isPaused.value = false
  isStreaming.value = false
  isPausing.value = false

  // 🆕 重置进度通知标题
  currentProgressTitle.value = '任务执行中'

  // Start execution
  loading.value = true

  // Clear previous execution results and status
  agentsStore.setExecutePlan([])
  stepExecutionStatus.value = {}
  sentStepIds.value.clear()
  currentExecutionId.value = null

  // Start batch executing first batch of ready steps
  await executeNextReadyBatch()
}

// View task process
async function handleTaskProcess() {
  drawerVisible.value = true
}

// Reset execution results
function handleRefresh() {
  agentsStore.setExecutePlan([])
}

// Add scroll state indicator
const isScrolling = ref(false)
let scrollTimer: ReturnType<typeof setTimeout> | null = null

// Modify scroll handler
function handleScroll() {
  isScrolling.value = true
  emit('refreshLine')
  // 清除之前的定时器
  if (scrollTimer) {
    clearTimeout(scrollTimer)
  }
  jsplumb.repaintEverything()

  // 设置滚动结束检测
  scrollTimer = setTimeout(() => {
    isScrolling.value = false
  }, 300) as ReturnType<typeof setTimeout>
}

// Modify mouse event handler
const handleMouseEnter = throttle(id => {
  if (!isScrolling.value) {
    createInternalLine(id)
  }
}, 0)

const handleMouseLeave = throttle(() => {
  if (!isScrolling.value) {
    createInternalLine()
  }
}, 0)

function clear() {
  jsplumb.reset()
}

// Encapsulate line redraw method
const redrawInternalLines = (highlightId?: string) => {
  // Waiting DOM 更新完成
  nextTick(() => {
    // 清除旧连线
    jsplumb.reset()

    // Waiting DOM 稳定后重新绘制
    setTimeout(() => {
      createInternalLine(highlightId)
    }, 100)
  })
}

// Watch collaborationProcess changes, auto redraw connections
watch(
  () => collaborationProcess,
  () => {
    redrawInternalLines()
  },
  { deep: true }
)

// Initialize connections after component mount
onMounted(() => {
  // 初始化时绘制连线
  nextTick(() => {
    setTimeout(() => {
      createInternalLine()
    }, 100)
  })
})

// Button interaction state management
const buttonHoverState = ref<'process' | 'execute' | 'refresh' | null>(null)
let buttonHoverTimer: ReturnType<typeof setTimeout> | null = null
const handleProcessMouseEnter = () => {
  if (buttonHoverTimer) {
    clearTimeout(buttonHoverTimer)
    buttonHoverTimer = null
  }
  buttonHoverState.value = 'process'
}

const handleExecuteMouseEnter = () => {
  if (buttonHoverTimer) {
    clearTimeout(buttonHoverTimer)
    buttonHoverTimer = null
  }
  if (agentsStore.agentRawPlan.data) {
    buttonHoverState.value = 'execute'
  }
}

const handleRefreshMouseEnter = () => {
  if (buttonHoverTimer) {
    clearTimeout(buttonHoverTimer)
    buttonHoverTimer = null
  }
  if (agentsStore.executePlan.length > 0) {
    buttonHoverState.value = 'refresh'
  }
}

const handleButtonMouseLeave = () => {
  // 添加防抖，防止快速切换时的抖动
  if (buttonHoverTimer) {
    clearTimeout(buttonHoverTimer)
  }
  buttonHoverTimer = setTimeout(() => {
    buttonHoverState.value = null
  }, 50) // 适当减少延迟时间
}

// Cleanup when leaving component
onUnmounted(() => {
  if (buttonHoverTimer) {
    clearTimeout(buttonHoverTimer)
  }
})
// Calculate button class names
const processBtnClass = computed(() => {
  if (buttonHoverState.value === 'refresh' || buttonHoverState.value === 'execute') {
    return 'circle'
  }
  return buttonHoverState.value === 'process' ? 'ellipse' : 'circle'
})

const executeBtnClass = computed(() => {
  if (buttonHoverState.value === 'process' || buttonHoverState.value === 'refresh') {
    return 'circle'
  }
  return agentsStore.agentRawPlan.data ? 'ellipse' : 'circle'
})

const refreshBtnClass = computed(() => {
  if (buttonHoverState.value === 'process' || buttonHoverState.value === 'execute') {
    return 'circle'
  }
  return agentsStore.executePlan.length > 0 ? 'ellipse' : 'circle'
})

// Calculate whether to show button text
const showProcessText = computed(() => {
  return buttonHoverState.value === 'process'
})

const showExecuteText = computed(() => {
  if (buttonHoverState.value === 'process') return false
  return agentsStore.agentRawPlan.data
})

const showRefreshText = computed(() => {
  return buttonHoverState.value === 'refresh'
})

// Calculate button titles
const processBtnTitle = computed(() => {
  return buttonHoverState.value === 'process' ? '查看任务流程' : '点击查看任务流程'
})

const executeBtnTitle = computed(() => {
  return showExecuteText.value ? '任务执行' : '点击执行任务'
})

const refreshBtnTitle = computed(() => {
  return showRefreshText.value ? '重置结果' : '点击重置执行状态'
})

defineExpose({
  createInternalLine,
  clear
})
</script>

<template>
  <div
    class="h-full flex flex-col relative"
    id="task-results"
    :class="{ 'is-running': agentsStore.executePlan.length > 0 }"
  >
    <!-- Notification 通知系统 -->
    <Notification :notifications="notifications" @close="id => removeNotification(id)" />

    <!--  标题与执行按钮 -->
    <div class="text-[18px] font-bold mb-[7px] flex justify-between items-center px-[20px]">
      <span class="text-[var(--color-text-title-header)]">执行结果</span>
      <div
        class="flex items-center justify-end gap-[10px] task-button-group w-[230px]"
        @mouseleave="handleButtonMouseLeave"
      >
        <!-- 刷新按钮 -->
        <el-button
          :class="refreshBtnClass"
          :color="variables.tertiary"
          :title="refreshBtnTitle"
          :disabled="agentsStore.executePlan.length === 0"
          @mouseenter="handleRefreshMouseEnter"
          @click="handleRefresh"
          style="order: 0"
        >
          <svg-icon icon-class="refresh" />
          <span v-if="showRefreshText" class="btn-text">重置</span>
        </el-button>
        <!-- Task Process按钮 -->
        <el-button
          :class="processBtnClass"
          :color="variables.tertiary"
          :title="processBtnTitle"
          @mouseenter="handleProcessMouseEnter"
          @click="handleTaskProcess"
          style="order: 1"
        >
          <svg-icon icon-class="process" />
          <span v-if="showProcessText" class="btn-text">任务过程</span>
        </el-button>

        <!-- Execute按钮 -->
        <el-popover
          :disabled="Boolean(agentsStore.agentRawPlan.data)"
          title="请先输入任务再执行"
          :visible="showPopover"
          @hide="showPopover = false"
          style="order: 2"
        >
          <template #reference>
            <el-button
              :class="executeBtnClass"
              :color="variables.tertiary"
              :title="isStreaming ? (isPaused ? '点击继续执行' : '点击暂停执行') : executeBtnTitle"
              :disabled="
                !agentsStore.agentRawPlan.data || (!isStreaming && loading) || isButtonLoading
              "
              @mouseenter="handleExecuteMouseEnter"
              @click="handleExecuteButtonClick"
            >
              <!-- 按钮短暂加载状态（防止双击） -->
              <svg-icon v-if="isButtonLoading" icon-class="loading" class="animate-spin" />

              <!-- 执行中加载状态（已废弃，保留以防万一） -->
              <svg-icon
                v-else-if="loading && !isStreaming"
                icon-class="loading"
                class="animate-spin"
              />

              <!-- 流式传输中且正在暂停（等待当前动作完成）：显示Loading图标 -->
              <svg-icon
                v-else-if="isStreaming && isPausing"
                icon-class="loading"
                size="20px"
                class="btn-icon animate-spin"
              />

              <!-- 流式传输中且未暂停：显示Pause图标 -->
              <svg-icon
                v-else-if="isStreaming && !isPaused && !isPausing"
                icon-class="Pause"
                size="20px"
                class="btn-icon"
              />

              <!-- 流式传输中且已暂停：显示播放/Resume图标 -->
              <svg-icon
                v-else-if="isStreaming && isPaused"
                icon-class="video-play"
                size="20px"
                class="btn-icon"
              />

              <!-- 默认状态：显示 action 图标 -->
              <svg-icon v-else icon-class="action" />

              <span v-if="showExecuteText && !isStreaming" class="btn-text">任务执行</span>
              <span v-else-if="isStreaming && isPaused" class="btn-text">继续执行</span>
              <span v-else-if="isStreaming && isPausing" class="btn-text">暂停中...</span>
              <span v-else-if="isStreaming" class="btn-text">暂停执行</span>
            </el-button>
          </template>
        </el-popover>

        <el-drawer
          v-model="drawerVisible"
          title="任务过程"
          direction="rtl"
          size="30%"
          :destroy-on-close="false"
        >
          <!-- 头部工具栏 -->
          <template #header>
            <div class="drawer-header">
              <span class="title">任务过程</span>
              <!-- <el-button v-if="!editMode" text icon="Edit" @click="editMode = true" />
              <el-button v-else text icon="Check" @click="save" /> -->
            </div>
          </template>
          <el-scrollbar height="calc(100vh - 120px)">
            <el-empty v-if="!collaborationProcess.length" description="暂无任务过程" />
            <div v-else class="process-list">
              <!-- 使用ProcessCard组件显示每个AgentSelection -->
              <ProcessCard
                v-for="step in collaborationProcess"
                :key="step.Id"
                :step="step"
                @open-edit="handleOpenEdit"
                @save-edit="handleSaveEdit"
              />
            </div>
          </el-scrollbar>
        </el-drawer>
      </div>
    </div>
    <!-- 内容 -->
    <div
      v-loading="agentsStore.agentRawPlan.loading"
      class="flex-1 overflow-auto relative ml-[20px] mr-[20px]"
      @scroll="handleScroll"
    >
      <div id="task-results-main" class="px-[40px] relative">
        <!-- 额外产物卡片 -->
        <div
          v-if="agentsStore.additionalOutputs && agentsStore.additionalOutputs.length > 0"
          class="mt-6"
          :key="`additional-outputs-${agentsStore.additionalOutputs.length}`"
        >
          <div class="space-y-4 mb-4">
            <AdditionalOutputCard
              v-for="(_, index) in agentsStore.additionalOutputs"
              :key="`additional-${index}-${agentsStore.additionalOutputs[index]}`"
              :index="index"
            />
          </div>
        </div>
        <!-- 原有的流程和产物 -->
        <div v-for="item in collaborationProcess" :key="item.Id" class="card-item">
          <el-card
            class="card-item w-full relative"
            :class="agentsStore.currentTask?.StepName === item.StepName ? 'active-card' : ''"
            :id="`task-results-${item.Id}-0`"
            @click="emit('setCurrentTask', item)"
          >
            <div class="text-[18px] mb-[15px]">{{ item.StepName }}</div>
            <!--  折叠面板 -->
            <el-collapse @change="handleCollapse">
              <el-collapse-item
                v-for="item1 in item.TaskProcess"
                :key="`task-results-${item.Id}-${item1.ID}`"
                :name="`task-results-${item.Id}-${item1.ID}`"
                :disabled="!hasActionResult(item, item1.ID)"
                @mouseenter="() => handleMouseEnter(`task-results-${item.Id}-0-${item1.ID}`)"
                @mouseleave="handleMouseLeave"
              >
                <!-- 执行中且没有结果时显示 loading 图标（暂停后不显示） -->
                <template v-if="loading && !hasActionResult(item, item1.ID) && !isPaused" #icon>
                  <SvgIcon icon-class="loading" size="20px" class="animate-spin" />
                </template>
                <!-- 暂停状态且没有结果时显示空白 -->
                <template v-else-if="isPaused && !hasActionResult(item, item1.ID)" #icon>
                  <span></span>
                </template>
                <!-- 没有执行计划时隐藏图标 -->
                <template v-else-if="!agentsStore.executePlan.length" #icon>
                  <span></span>
                </template>
                <!-- 有结果时不提供 #icon，让 Element Plus 显示默认箭头 -->
                <template #title>
                  <!-- 运行之前背景颜色是var(--color-bg-detail-list),运行之后背景颜色是var(--color-bg-detail-list-run) -->
                  <div
                    class="flex items-center gap-[15px] rounded-[20px]"
                    :class="{
                      'bg-[var(--color-bg-detail-list)]': !hasActionResult(item, item1.ID),
                      'bg-[var(--color-bg-detail-list-run)]': hasActionResult(item, item1.ID)
                    }"
                  >
                    <!--  右侧链接点 -->
                    <div
                      class="absolute right-0 top-1/2 transform -translate-y-1/2"
                      :id="`task-results-${item.Id}-0-${item1.ID}`"
                    ></div>
                    <div
                      class="w-[41px] h-[41px] rounded-full flex items-center justify-center"
                      :style="{ background: getAgentMapIcon(item1.AgentName).color }"
                    >
                      <svg-icon
                        :icon-class="getAgentMapIcon(item1.AgentName).icon"
                        color="#fff"
                        size="24px"
                      />
                    </div>
                    <div class="text-[16px]">
                      <span
                        :class="{
                          'text-[var(--color-text-result-detail)]': !hasActionResult(
                            item,
                            item1.ID
                          ),
                          'text-[var(--color-text-result-detail-run)]': hasActionResult(
                            item,
                            item1.ID
                          )
                        }"
                        >{{ item1.AgentName }}:&nbsp; &nbsp;</span
                      >
                      <span :style="{ color: getActionTypeDisplay(item1.ActionType)?.color }">
                        {{ getActionTypeDisplay(item1.ActionType)?.name }}
                      </span>
                    </div>
                  </div>
                </template>
                <ExecutePlan
                  :action-id="item1.ID"
                  :node-id="item.StepName"
                  :execute-plans="agentsStore.executePlan"
                />
              </el-collapse-item>
            </el-collapse>
          </el-card>

          <el-card
            class="card-item w-full relative output-object-card"
            :class="agentsStore.currentTask?.StepName === item.StepName ? 'active-card' : ''"
            :id="`task-results-${item.Id}-1`"
            @click="emit('setCurrentTask', item)"
          >
            <!--            <div class="text-[18px]">{{ item.OutputObject }}</div>-->
            <el-collapse @change="handleCollapse" :key="agentsStore.executePlan.length">
              <el-collapse-item
                class="output-object"
                :disabled="!hasObjectResult(item.OutputObject)"
              >
                <!-- 执行中且没有结果时显示 loading 图标（暂停后不显示） -->
                <template v-if="loading && !hasObjectResult(item.OutputObject) && !isPaused" #icon>
                  <SvgIcon icon-class="loading" size="20px" class="animate-spin" />
                </template>
                <!-- 暂停状态且没有结果时显示空白 -->
                <template v-else-if="isPaused && !hasObjectResult(item.OutputObject)" #icon>
                  <span></span>
                </template>
                <!-- 没有执行计划时隐藏图标 -->
                <template v-else-if="!agentsStore.executePlan.length" #icon>
                  <span></span>
                </template>
                <!-- 有结果时不提供 #icon，让 Element Plus 显示默认箭头 -->
                <template #title>
                  <div
                    class="text-[18px]"
                    :class="{
                      'text-[var(--color-text-result-detail)]': !hasObjectResult(item.OutputObject),
                      'text-[var(--color-text-result-detail-run)]': hasObjectResult(
                        item.OutputObject
                      )
                    }"
                  >
                    {{ item.OutputObject }}
                  </div>
                </template>
                <ExecutePlan
                  :node-id="item.OutputObject"
                  :execute-plans="agentsStore.executePlan"
                />
              </el-collapse-item>
            </el-collapse>
          </el-card>
        </div>
      </div>
    </div>
  </div>
</template>

<style scoped lang="scss">
#task-results.is-running {
  --color-bg-detail-list: var(--color-bg-detail-list-run); // 直接指向 100 % 版本
}
#task-results {
  :deep(.el-collapse) {
    border: none;
    border-radius: 20px;
    .el-collapse-item + .el-collapse-item {
      margin-top: 10px;
    }

    .el-collapse-item__header {
      border: none;
      background: var(--color-bg-detail-list-run);
      min-height: 41px;
      line-height: 41px;
      border-radius: 20px;
      transition: border-radius 1ms;
      position: relative;

      .el-collapse-item__title {
        background: var(--color-bg-detail-list);
        border-radius: 20px;
      }

      .el-icon {
        font-size: 20px;
        font-weight: 900;
        background: var(--color-bg-icon-rotate);
        border-radius: 50px;
        color: #d8d8d8;
      }

      &.is-active {
        border-bottom-left-radius: 0;
        border-bottom-right-radius: 0;
      }
    }

    .output-object {
      .el-collapse-item__header {
        background: none;

        .el-collapse-item__title {
          background: none;
        }
      }

      .el-collapse-item__wrap {
        background: none;

        .card-item {
          background: var(--color-bg-detail);
          padding: 5px;
          padding-top: 10px;
          border-radius: 7px;
        }
      }
    }

    .el-collapse-item__wrap {
      border: none;
      background: var(--color-bg-detail-list);
      border-bottom-left-radius: 20px;
      border-bottom-right-radius: 20px;
    }
  }

  :deep(.el-card) {
    .el-card__body {
      padding-right: 40px;
      background-color: var(--color-bg-detail);
      &:hover {
        background-color: var(--color-card-bg-result-hover);
      }
    }
  }

  .output-object-card {
    :deep(.el-card__body) {
      padding-top: 0;
      padding-bottom: 0;
      padding-right: 0;
    }
  }

  .active-card {
    background: linear-gradient(var(--color-bg-tertiary), var(--color-bg-tertiary)) padding-box,
      linear-gradient(to right, #00c8d2, #315ab4) border-box;
  }

  .card-item + .card-item {
    margin-top: 10px;
  }

  .additional-output-card {
    border: 1px dashed #dcdfe6;
    opacity: 0.9;
    box-shadow: var(--color-agent-list-hover-shadow);

    &:hover {
      border-color: #409eff;
      opacity: 1;
    }

    :deep(.el-card__body) {
      padding: 20px;
    }

    // 编辑区域样式调整
    .el-collapse {
      border: none;

      .el-collapse-item {
        .el-collapse-item__header {
          background: var(--color-bg-detail);
          min-height: 36px;
          line-height: 36px;
          border-radius: 8px;

          .el-collapse-item__title {
            background: transparent;
            font-size: 14px;
            padding-left: 0;
          }

          .el-icon {
            font-size: 16px;
          }
        }

        .el-collapse-item__wrap {
          background: var(--color-bg-detail);
          border-radius: 0 0 8px 8px;
        }
      }
    }
  }

  //按钮交互样式
  .task-button-group {
    display: flex;
    flex-direction: row-reverse;
    .el-button {
      display: inline-flex !important;
      align-items: center !important;
      justify-content: center !important;
      transition: width 0.2s ease-out, padding 0.2s ease-out, border-radius 0.2s ease-out,
        transform 0.2s ease-out, box-shadow 0.2s ease-out, filter 0.2s ease-out !important;
      overflow: hidden !important;
      white-space: nowrap !important;
      border: 1px solid transparent !important;
      border-color: transparent !important;
      color: var(--color-text-primary) !important;
      position: relative;
      background-color: var(--color-bg-tertiary) !important;
      gap: 0px !important;
      outline: none !important;
      box-shadow: none !important;
      -webkit-tap-highlight-color: transparent !important;
      backface-visibility: hidden !important;
      -webkit-backface-visibility: hidden !important;
      transform: translateZ(0) !important;
      will-change: transform, width, padding, border-radius !important;

      &::before,
      &::after {
        display: none !important;
      }

      &:hover {
        transform: translateY(-2px) translateZ(0) !important;
        box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15) !important;
        filter: brightness(1.1) !important;
        border-color: transparent !important;
      }

      &.is-disabled {
        opacity: 0.5;
        cursor: not-allowed !important;

        &:hover {
          transform: none !important;
          box-shadow: none !important;
          filter: none !important;
        }
      }
    }

    // Circle state
    .circle {
      width: 40px !important;
      height: 40px !important;
      min-width: 40px !important;
      max-width: 40px !important;
      padding: 0 !important;
      border-radius: 50% !important;

      .btn-text {
        display: none !important;
      }
    }

    // Ellipse state
    .ellipse {
      height: 40px !important;
      border-radius: 20px !important;
      padding: 0 16px !important;
      gap: 8px !important;

      // Task process button - fixed left, expand right
      &:nth-child(1) {
        justify-content: flex-start !important;

        .btn-text {
          display: inline-block !important;
          font-size: 14px;
          font-weight: 500;
          margin-right: 8px;
          margin-left: 0;
          opacity: 1;
          animation: fadeInLeft 0.3s ease forwards;
        }
      }

      // Task execution button - fixed right, expand left
      &:nth-child(2) {
        justify-content: flex-end !important;

        .btn-text {
          display: inline-block !important;
          font-size: 14px;
          font-weight: 500;
          margin-left: 8px;
          margin-right: 0;
          opacity: 1;
          animation: fadeInRight 0.3s ease forwards;
        }
      }

      // .btn-text {
      //   display: inline-block !important;
      //   font-size: 14px;
      //   font-weight: 500;
      //   margin-left: 4px;
      //   opacity: 1;
      //   animation: fadeIn 0.3s ease forwards;
      // }
    }

    @keyframes fadeInLeft {
      from {
        opacity: 0;
        transform: translateX(5px);
      }
      to {
        opacity: 1;
        transform: translateX(0);
      }
    }

    @keyframes fadeInRight {
      from {
        opacity: 0;
        transform: translateX(-5px);
      }
      to {
        opacity: 1;
        transform: translateX(0);
      }
    }

    // 按钮图标间距
    .btn-icon {
      margin-right: 8px !important;
    }
  }
}
</style>
