<template>
  <div>
    <div class="right-panel">
      <div style="display: flex; align-items: center">
        <h3 style="margin: 0; flex-grow: 1">处理算法计算</h3>
        <div class="custom-icon-plans">
          <el-button type="primary" @click="startCalculate">开始</el-button>
          <el-button type="warning" @click="pauseCalculate">暂停</el-button>
          <el-button type="danger" @click="stopCalculate">停止</el-button>
        </div>
      </div>


      <div class="flow-container" ref="flowContainer">
        <!-- 连接线画布 -->
        <svg class="connector-canvas" :width="flowContainer?.offsetWidth" :height="flowContainer?.offsetHeight">
          <path v-for="(conn, index) in connections" :key="'conn-' + index" :d="conn.path" class="connection-line"
            marker-end="url(#arrowhead)" />
          <defs>
            <marker id="arrowhead" viewBox="0 0 10 10" refX="8" refY="5" markerWidth="6" markerHeight="6" orient="auto">
              <path d="M 0 0 L 10 5 L 0 10 z" class="arrow-head" />
            </marker>
          </defs>
        </svg>

        <div class="flow-plans" style="padding-top: 20px">
          <div v-for="(plan, index) in plans" :key="'plan-' + plan.id" ref="buttonRefs" class="flow-button-wrapper"
            :style="{
              transform: `translate(${plan.position.x}px, ${plan.position.y}px)`
            }">
            <el-button class="plan-button" :style="progressStyle(index)" @click="viewResult(index)">
              {{ plan.algorithm.label }}
            </el-button>
          </div>
        </div>
      </div>
    </div>
    <!-- 用于展示结果视图的modal框 -->
    <el-dialog v-model="showModal" title="选择展示方式" :close-on-click-modal="false" :show-close="false" width="80%">
      <!-- 操作按钮区域 -->
      <div class="mode-buttons">
        <el-button type="primary" @click="switchView('chart')">
          <el-icon>
            <PieChart />
          </el-icon>
          以图表视图查看
        </el-button>

        <el-button type="success" @click="switchView('3d')">
          <el-icon>
            <Promotion />
          </el-icon>
          以3D视图查看
        </el-button>

        <el-button type="warning" @click="switchView('vr')">
          <el-icon>
            <VideoCamera />
          </el-icon>
          以VR视图查看
        </el-button>
      </div>
      <!-- 动态内容区域 -->
      <div class="content-area">
        <template v-if="currentView">
          <component :is="currentViewComponent" :plan="currentResult" />
        </template>
        <el-empty v-else description="请选择视图展示方式" class="empty-tip">
          <template #image>
            <el-icon :size="80" color="var(--el-color-info)">
              <Select />
            </el-icon>
          </template>
          <div class="tip-text">
            点击上方按钮选择查看方式
          </div>
        </el-empty>
      </div>

      <template #footer>
        <el-button @click="closeModal">关闭</el-button>
      </template>
    </el-dialog>
  </div>
</template>
<script setup>
import { inject, onMounted, onUnmounted, ref, computed, defineAsyncComponent, shallowRef, watch, nextTick } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { postData, getData } from '@/api/axios.js'
import { useRoute } from 'vue-router'
import {
  PieChart,
  Promotion,
  VideoCamera,
  Select,
} from '@element-plus/icons-vue'

const useAnalyzeInfo = inject('analyzeInfo')
const plans = inject('plans')
const progress = ref(new Array(plans.length).fill(0))

const mission = useAnalyzeInfo.analyzeInfo.value.mission
const connections = ref([])
const flowContainer = ref(null)
const buttonRefs = ref(null)
const progressInterval = ref(null)

// 布局参数
const COLUMN_GAP = 300
const ROW_GAP = 100
const MAX_COLUMNS = 3
const MAX_ROWS = 5

// 视图展示控制变量
// 加载组件
const ChartView = defineAsyncComponent(() => import('./chartView.vue'))
const ThreeDView = defineAsyncComponent(() => import('./threeDView.vue'))
const VRView = defineAsyncComponent(() => import('./VRView.vue'))

// 状态管理
const showModal = ref(false)
const currentView = ref(null)
const currentResult = ref(null)

// 动态组件处理
const currentViewComponent = shallowRef(null)
const viewComponents = {
  'chart': ChartView,
  '3d': ThreeDView,
  'vr': VRView,
}

// 控制按钮内部进度条
// 动态样式计算
const progressStyle = (index) => {
  return computed(() => {
    const baseColor = getBaseColor(progress.value[index])
    const gradient = generateGradient(progress.value[index], baseColor)

    return {
      backgroundImage: gradient,
      backgroundColor: progress.value[index] === 100 ? baseColor : 'transparent'
    }
  }).value
}

// 获取基础颜色
const getBaseColor = (value) => {
  if (value >= 100) return 'rgba(100, 255, 100, 0.3)' // 绿色，表示任务完成
  if (value < 0) return 'rgba(255, 20, 20, 0.3)' // 红色，表示任务失败
  return 'rgba(66, 144, 255, 0.3)' // 蓝色，任务执行中，按比例显示
}

// 生成渐变背景
const generateGradient = (value, color) => {
  if (value <= 0 || value >= 100) return 'none' // 任务失败或任务完成都是完整显示，当存在不满进度时逐渐填满

  const percentage = `${Math.min(value, 100)}%`
  return `linear-gradient(
    to right,
    ${color} 0%,
    ${color} ${percentage},
    transparent ${percentage},
    transparent 100%
  )`
}

// 查看结果
const viewResult = (index) => {
  if (progress.value[index] == 100) {
    // 初始化视图显示框
    currentView.value = null
    currentViewComponent.value = null
    currentResult.value = plans.value[index].id
    showModal.value = true
  } else {
    ElMessage.warning("请先开始计算处理，或等待该任务完成")
  }

}

// 选择视图显示模式
const switchView = (type) => {
  currentView.value = type
  currentViewComponent.value = viewComponents[type]

}

// 关闭视图显示框
const closeModal = () => {
  showModal.value = false
  // 清空当前视图
  currentView.value = null
  currentResult.value = null
  currentViewComponent.value = null
}


// 再次绘制所有连接线
// 获取按钮中心坐标
const getButtonCenter = (plan) => {
  const index = plans.value.findIndex(b => b.id === plan.id)
  if (index === -1 || !buttonRefs.value[index]) return { x: 0, y: 0 }

  const el = buttonRefs.value[index]
  const containerRect = flowContainer.value.getBoundingClientRect()
  const planRect = el.getBoundingClientRect()

  return {
    x: planRect.left - containerRect.left + el.offsetWidth / 2,
    y: planRect.top - containerRect.top + el.offsetHeight / 2,
    top: planRect.top - containerRect.top,
    bottom: planRect.top - containerRect.top + el.offsetHeight,
    left: planRect.left - containerRect.left,
    right: planRect.left - containerRect.left + el.offsetWidth
  }
}

// 自动布局计算
const calculateLayout = () => {
  nextTick(() => {
    const container = flowContainer.value
    if (!container) return

    const containerWidth = container.offsetWidth
    const layoutMap = new Map() // 使用Map记录行列位置

    // 第一代按钮布局
    let currentRow = 0
    let currentCol = 0

    plans.value.forEach((btn) => {
      // 仅处理根节点按钮
      if (!btn.parentId) {
        btn.row = currentRow
        btn.col = currentCol
        currentCol++
        if (currentCol >= MAX_COLUMNS) {
          currentCol = 0
          currentRow++
        }
      }
    })

    // 子节点布局
    plans.value.forEach((btn) => {
      if (btn.parentId) {
        const parent = plans.value.find(b => b.id === btn.parentId)
        if (!parent) return

        // 处理换行
        if (btn.col >= MAX_COLUMNS) {
          btn.row += Math.floor(btn.col / MAX_COLUMNS)
          btn.col = btn.col % MAX_COLUMNS
        }
      }

      // 计算绝对位置（无响应式更新）
      const pos = {
        x: 20 + btn.col * COLUMN_GAP,
        y: btn.row * ROW_GAP
      }

      // 直接赋值避免触发响应式更新
      if (btn.position.x !== pos.x || btn.position.y !== pos.y) {
        btn.position.x = pos.x
        btn.position.y = pos.y
      }
    })
    setTimeout(() => {
      updateConnections()
    }, 200)

  })
}

// 更新连接线
const updateConnections = () => {
  connections.value = []
  // 遍历所有按钮建立连接关系
  plans.value.forEach(plan => {
    if (plan.parentId) {
      const parent = plans.value.find(b => b.id === plan.parentId)
      if (!parent) return

      // 获取实际渲染位置
      const start = getButtonCenter(parent)
      const end = getButtonCenter(plan)
      // 除初始节点的并行外，均为父下到子上
      if (plan.row !== 0) {
        if (start.x > 0 && start.y > 0 && end.x > 0 && end.y > 0) {
          connections.value.push({
            source: parent.id,
            target: plan.id,
            path: createSmartPath({ x: start.x, y: start.bottom }, { x: end.x, y: end.top })
          })
        }
      }
      // 如果第一行并行，则不做连线
    }
  })
}

// 创建曲线路径
const createSmartPath = (start, end) => {
  const deltaX = end.x - start.x
  const deltaY = end.y - start.y

  // // 水平连接优先
  // if (Math.abs(deltaX) > 50) {
  //   const cp1 = { x: start.x + deltaX * 0.8, y: start.y }
  //   const cp2 = { x: end.x - deltaX * 0.2, y: end.y }
  //   return `M ${start.x} ${start.y} C ${cp1.x} ${cp1.y}, ${cp2.x} ${cp2.y}, ${end.x} ${end.y}`
  // }

  // 垂直连接
  const cp1 = { x: start.x + deltaX * 0.3, y: start.y + deltaY * 0.2 }
  const cp2 = { x: end.x - deltaX * 0.3, y: end.y - deltaY * 0.8 }
  return `M ${start.x} ${start.y} C ${cp1.x} ${cp1.y}, ${cp2.x} ${cp2.y}, ${end.x} ${end.y}`
}

const startCalculate = async () => {
  // // 测试用模拟进度100%
  // progress.value.forEach((item, index) => progress.value[index] = 100)
  // return

  // 真实调用后台数据处理
  const response = await postData('/calculate/', {
    mission: mission.id,
    command: 'start',
  })
  progressInterval.value = setInterval(async () => {
    try {
      const response = await getData('/results', { 'mission': JSON.stringify(mission) })
      // 成功获取进度更新信息，将进度赋值给progress
      console.log(response)
      if (response.status === "success") {
        // 任务是否全部完成
        let missionComplete = true
        // 任务是否发生失败
        let missionFailed = false
        response.data.forEach(result => {
          // 查找序号，根据序号修改progress
          const index = plans.value.findIndex(p => p.id === result.planId)
          progress.value[index] = result.progress
          // 只要有一个没有全部完成的任务，就不会停止获取进度
          if (result.progress !== 100) {
            missionComplete = false
          }
          if (result.progress == -1 || result.progress == -2) {
            // -1表示单个任务中止

            // -2表示整个任务中止

          }
        })
        if (missionComplete) {
          ElMessageBox.alert("任务已全部完成", "", {
            confirmButtonText: '确定',
          })
          clearInterval(progressInterval.value)
        }
      } else {
        ElMessage.error("更新任务信息失败,", response.message)
      }
    } catch (error) {
      console.log("catch error when start interval", error)
      clearInterval(progressInterval.value)
    }
  }, 2000) // 2s更新一次
}

const pauseCalculate = async () => {
  console.log('pause')

  try {
    //暂停、停止时都清除定时器
    clearInterval(progressInterval.value)
    // 发送暂停请求
    const response = await postData('/calculate/', {
      mission: mission.id,
      command: 'pause',
    })
  } catch (error) {
    console.log(error)
  }
  //暂停时需要发送暂停请求
  // todos
}

const stopCalculate = async () => {
  console.log('stop')
  //暂停、停止时都清除定时器
  try {
    clearInterval(progressInterval.value)
    // 发送暂停请求
    const response = await postData('/calculate/', {
      mission: mission.id,
      command: 'stop',
    })
  } catch (error) {
    console.log(error)
  }
  //停止时需要发送停止请求
  // todos
}

onMounted(() => {
  setTimeout(() => {
    calculateLayout()
    updateConnections()
  }, 500)
})

onUnmounted(() => {
  try {
    clearInterval(progressInterval.value)
  } catch (error) {
    console.log(error)
  }
})

const route = useRoute();
// 监听路由变化
watch(
  () => route.path,
  (newPath) => {
    // 路由变为plan时，修改显示内容
    if (newPath === '/dashboard/analyze/plan/calculate') {
      setTimeout(() => {
        calculateLayout()
        updateConnections()
      }, 500)
    }
  },
  { immediate: true }
);

</script>
<style lang="scss" scoped>
.container {
  width: 100%;
  height: 800px;
  display: flex;
  margin: 0 auto;
}

.connector-canvas {
  position: absolute;
  top: 0;
  left: 0;
  z-index: 1;
}

.flow-plans {
  position: relative;
  z-index: 2;
  display: inline-grid;
  grid-template-areas: "main";
  margin: 20px;
}

.left-panel {
  flex: 1;
  padding: 20px;
  margin-right: 20px;
}

.right-panel {
  flex: 3;
  padding: 20px;
  position: relative;
}

.stats-item {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.flow-container {
  position: relative;
  height: 600px;
  border: 1px dashed #ccc;
  margin: 20px 0;
}

.flow-button-wrapper {
  width: 180px;
  position: absolute;
  transition: all 0.3s;
}

.button-actions {
  position: absolute;
  right: -30px;
  bottom: -30px;
  display: flex;
  flex-direction: column;
  column-gap: 1px;
}

.flow-plans {
  position: relative;
  min-height: 400px;
}

:deep(.plan-button) {
  --el-button-text-color: #000;
  --el-button-hover-text-color: #000;
}

.plan-button {
  grid-area: main;
  position: relative;
  width: 100%;
  padding: 12px 24px;
}


.floating-controls {
  position: absolute;
  grid-area: main;
  z-index: 2000;
}

.delete-plan {
  position: absolute;
  top: -32px;
  left: 50%;
  transform: translateX(-50%);
  border: solid rgba(256, 100, 140, 0.2);
  background-color: rgba(256, 100, 140, 0.2);
  ;
}

.right-arrow {
  position: absolute;
  right: -138px;
  top: 50%;
  border: solid rgba(13, 161, 13, 0.2);
  background-color: rgba(13, 161, 13, 0.2);
}

.down-arrow {
  position: absolute;
  bottom: -64px;
  left: 50%;
  transform: translateX(-50%);
  border: solid rgba(13, 161, 13, 0.2);
  background-color: rgba(13, 161, 13, 0.2);
}

.flow-button-wrapper {
  position: absolute;
  transition: all 0.3s ease;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
}

.button-actions {
  display: flex;
  gap: 8px;
  position: absolute;
  right: -40px;
  bottom: -40px;
}

.connection-line {
  stroke: #409EFF;
  stroke-width: 2;
  fill: none;
  transition: d 0.3s ease;
}

.arrow-head {
  /* stroke: #409EFF; */
  stroke-width: 2;
  fill: #409EFF;
  transition: d 0.3s ease;
}

.custom-icon-plans {
  display: flex;
  gap: 12px;
}


.mode-buttons {
  margin-bottom: 20px;
  display: flex;
  gap: 15px;
  justify-content: center;
}

.content-area {
  min-height: 600px;
  border: 1px solid var(--el-border-color);
  border-radius: var(--el-border-radius-base);
  position: relative;
}

.empty-tip {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 100%;
}

.tip-text {
  color: var(--el-text-color-secondary);
  margin-top: 10px;
  font-size: 14px;
}

/* 按钮图标样式 */
.el-button [class*=el-icon]+span {
  margin-left: 6px;
}
</style>