<script setup lang="ts">
import { computed, onUnmounted, ref } from 'vue'
import { throttle } from 'lodash'
import { AnchorLocations, BezierConnector } from '@jsplumb/browser-ui'

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 } from '@/stores'
import api, { type IExecuteRawResponse } from '@/api'

import ExecutePlan from './ExecutePlan.vue'
import Iod from './Iod.vue'


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

const agentsStore = useAgentsStore()

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

const jsplumb = new Jsplumb('task-results-main', {
  connector: {
    type: BezierConnector.type,
    options: { curviness: 30, stub: 10 },
  },
})

// 操作折叠面板时要实时的刷新连线
let timer: number
function handleCollapse() {
  if (timer) {
    clearInterval(timer)
  }
  timer = setInterval(() => {
    jsplumb.repaintEverything()
    emit('refreshLine')
  }, 1)

  // 默认三秒后已经完全打开
  const timer1 = setTimeout(() => {
    clearInterval(timer)
  }, 3000)

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

// 创建内部连线
function createInternalLine(id?: string) {
  const arr: ConnectArg[] = []
  jsplumb.reset()
  collaborationProcess.value.forEach((item) => {
    // 创建左侧流程与产出的连线
    // jsplumb.connect(`task-results-${item.Id}-0`, `task-results-${item.Id}-1`, [
    //   AnchorLocations.Left,
    //   AnchorLocations.Left,
    // ])
    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 ?? '')) {
        // jsplumb.connect(
        //   `task-results-${jitem.Id}-1`,
        //   `task-results-${item.Id}-0`,
        //   [AnchorLocations.Left, AnchorLocations.Left],
        //   {
        //     type: 'output',
        //   },
        // )
        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-${jitem.Id}-0-${i.ID}`
          const targetId = `task-results-${item.Id}-1`
          // jsplumb.connect(sourceId, targetId, [AnchorLocations.Right, AnchorLocations.Right], {
          //   stops: [
          //     [0, color],
          //     [1, color],
          //   ],
          //   transparent: sourceId !== id,
          // })
          arr.push({
            sourceId,
            targetId,
            anchor: [AnchorLocations.Right, AnchorLocations.Right],
            config: {
              stops: [
                [0, color],
                [1, color],
              ],
              transparent: sourceId !== 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-${i.ID}`
          const targetId = `task-results-${item.Id}-0-${i2.ID}`
          // jsplumb.connect(sourceId, targetId, [AnchorLocations.Right, AnchorLocations.Right], {
          //   stops: [
          //     [0, color],
          //     [1, color],
          //   ],
          //   transparent: sourceId !== id,
          // })
          arr.push({
            sourceId,
            targetId,
            anchor: [AnchorLocations.Right, AnchorLocations.Right],
            config: {
              stops: [
                [0, color],
                [1, color],
              ],
              transparent: sourceId !== id,
            },
          })
        }
      })
    })
  })

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

const results = ref<IExecuteRawResponse[]>([])
const loading = ref(false)
async function handleRun() {
  try {
    loading.value = true
    results.value = await api.executePlan(agentsStore.agentRawPlan.data!)
  } finally {
    loading.value = false
  }
}

// 添加滚动状态标识
const isScrolling = ref(false)
let scrollTimer: number

// 修改滚动处理函数
function handleScroll() {
  isScrolling.value = true
  emit('refreshLine')
  // 清除之前的定时器
  if (scrollTimer) {
    clearTimeout(scrollTimer)
  }
  jsplumb.repaintEverything()

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

// 修改鼠标事件处理函数
const handleMouseEnter = throttle((id) => {
  if (!isScrolling.value) {
    createInternalLine(id)
  }
}, 100)

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

defineExpose({
  createInternalLine,
})
</script>

<template>
  <div class="h-full flex flex-col relative" id="task-results">
    <!--  标题与执行按钮 -->
    <div class="text-[18px] font-bold mb-[18px] flex justify-between items-center px-[20px]">
      <span>执行结果</span>
      <div class="flex items-center gap-[14px]">
        <el-button circle :color="variables.tertiary" disabled title="点击刷新">
          <svg-icon icon-class="refresh" />
        </el-button>
        <el-button circle :color="variables.tertiary" title="点击运行" @click="handleRun">
          <svg-icon icon-class="action" />
        </el-button>
      </div>
    </div>
    <!-- 内容 -->
    <div
      v-loading="agentsStore.agentRawPlan.loading"
      class="flex-1 overflow-auto relative"
      @scroll="handleScroll"
    >
      <div id="task-results-main" class="px-[40px] relative">
        <div v-for="item in collaborationProcess" :key="item.Id" class="card-item">
          <el-card
            class="card-item w-full relative"
            shadow="hover"
            :id="`task-results-${item.Id}-0`"
            @click="emit('setCurrentTask', item)"
          >
            <div class="text-[18px] mb-[15px]">{{ item.StepName }}</div>
            <!--  折叠面板 -->
            <el-collapse @change="handleCollapse">
              <!--            <el-tooltip-->
              <!--              :disabled="Boolean(true || results.length || loading)"-->
              <!--              placement="top"-->
              <!--              effect="light"-->
              <!--              content="请点击右上角的循行按钮，查看运行结果"-->
              <!--            >-->
              <el-collapse-item
                v-for="item1 in item.TaskProcess"
                :key="`task-results-${item.Id}-${item1.ID}`"
                :name="`task-results-${item.Id}-${item1.ID}`"
                :disabled="Boolean(!results.length || loading)"
                @mouseenter="() => handleMouseEnter(`task-results-${item.Id}-0-${item1.ID}`)"
                @mouseleave="handleMouseLeave"
              >
                <template v-if="loading" #icon>
                  <SvgIcon icon-class="loading" size="20px" class="animate-spin" />
                </template>
                <template v-else-if="!results.length" #icon>
                  <span></span>
                </template>
                <template #title>
                  <div class="flex items-center gap-[15px]">
                    <!--  右侧链接点 -->
                    <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="var(--color-text)"
                        size="24px"
                      />
                    </div>
                    <div class="text-[16px]">
                      <span>{{ 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="results"
                />
              </el-collapse-item>
              <!--            </el-tooltip>-->
            </el-collapse>
          </el-card>

          <el-card
            class="card-item w-full relative"
            shadow="hover"
            :id="`task-results-${item.Id}-1`"
            @click="emit('setCurrentTask', item)"
          >
            <div class="text-[18px]">{{ item.OutputObject }}</div>
          </el-card>
        </div>
      </div>
    </div>
  </div>
</template>

<style scoped lang="scss">
#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-secondary);
      min-height: 41px;
      line-height: 41px;
      border-radius: 20px;
      transition: border-radius 1ms;
      position: relative;

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

      .el-icon {
        font-size: 20px;
        font-weight: bold;
      }

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

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

  :deep(.el-card) {
    .el-card__body {
      padding-right: 40px;
    }
  }

  .card-item + .card-item {
    margin-top: 10px;
  }
}
</style>
