<template>
  <div class="container">
    <!-- 左侧信息区域 -->
    <div class="left-panel">
      <h3 style="margin: 0">网络基本信息</h3>
      <el-card v-loading="loading" style="margin-top: 30px">
        <el-form label-width="80px">
          <el-form-item label="节点信息">
            <div class="stats-item">
              <span>S型节点数: {{ nodeData.sNodes }}</span>
              <span>D型节点数: {{ nodeData.dNodes }}</span>
              <span>I型节点数: {{ nodeData.iNodes }}</span>
            </div>
          </el-form-item>

          <el-form-item>
            <div class="stats-item">
              <el-tooltip content="聚焦节点说明" placement="top">
                <span>聚焦节点数: {{ nodeData.num }}</span>
              </el-tooltip>
              <el-tooltip content="孤立节点说明" placement="top">
                <span>孤立节点数: {{ nodeData.num }}</span>
              </el-tooltip>
              <el-tooltip content="总节点说明" placement="top">
                <span>总节点数: {{ nodeData.num }}</span>
              </el-tooltip>
            </div>
          </el-form-item>

          <el-form-item label="边信息">
            <div class="stats-item">
              <el-tooltip content="边集中度说明" placement="top">
                <span>边集中度: {{ edgeData.concentration }}</span>
              </el-tooltip>
              <span>总边数: {{ edgeData.num }}</span>
            </div>
          </el-form-item>
        </el-form>
      </el-card>
    </div>

    <!-- 右侧操作区域 -->
    <div v-if="planning" class="right-panel">
      <div style="display: flex; align-items: center">
        <h3 style="margin: 0; flex-grow: 1">处理流程规划</h3>
        <div v-if="planning"><el-button type="success" @click="submitPlan">
            提交处理规划
          </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-buttons" style="padding-top: 20px">
          <div v-for="(btn, index) in buttons" :key="'btn-' + btn.id" ref="buttonRefs" class="flow-button-wrapper"
            :style="{
              transform: `translate(${btn.position.x}px, ${btn.position.y}px)`
            }" @mouseenter="btn.showExtraBtns = true" @mouseleave="hideExtraBtns(index)">
            <el-dropdown trigger="click" @visible-change="(visible) => menuVisible[index] = visible"
              style="width: 100%">
              <el-button :type="selectedAlgorithms[index] ? 'primary' : ''" class="plan-button">
                {{ btn.label }}
                <el-icon class="el-icon--right">
                  <arrow-down />
                </el-icon>
              </el-button>

              <template #dropdown>
                <el-dropdown-menu>
                  <el-dropdown-item v-for="algorithm in btn.algorithms" :key="algorithm.value"
                    @click="selectAlgorithm(index, algorithm)">
                    {{ algorithm.label }}
                  </el-dropdown-item>
                </el-dropdown-menu>
              </template>
            </el-dropdown>

            <!-- 浮动控制按钮 -->
            <div v-show="btn.showExtraBtns" class="floating-controls">
              <!-- 删除按钮（上） -->
              <div><el-button v-show="btn.id !== 1" class="delete-btn" :icon="Delete" @click.stop="handleDelete(btn)">
                </el-button>
              </div>
              <!-- 向右箭头（右） -->
              <div><el-button v-show="canExpandRight(btn)" class="right-arrow" :icon="ArrowRight"
                  @click.stop="addButton(index, 'right')" :disabled="checkHorizontalLimit(btn)" /></div>
              <!-- 向下箭头（下） -->
              <div><el-button v-show="canExpandBottom(btn)" class="down-arrow" :icon="ArrowDown"
                  @click.stop="addButton(index, 'bottom')" :disabled="checkVerticalLimit(btn)" /></div>
            </div>
          </div>
        </div>
      </div>
    </div>
    <div v-if="calculating" class="right-panel">
      <router-view></router-view>
    </div>
  </div>
</template>

<script setup>
import { ref, reactive, onMounted, nextTick, inject, provide } from 'vue'
import { ElMessage } from 'element-plus'
import { useRouter } from 'vue-router'
import { Delete, ArrowDown, ArrowRight, VideoPlay, VideoPause, SwitchButton } from '@element-plus/icons-vue'
import { getData, postData, deleteData } from '@/api/axios.js'
import { pl } from 'element-plus/es/locales.mjs'


const useAnalyzeInfo = inject('analyzeInfo')
const router = useRouter()

const nodeData = useAnalyzeInfo.analyzeInfo.value.nodeFile
const edgeData = useAnalyzeInfo.analyzeInfo.value.edgeFile
const mission = useAnalyzeInfo.analyzeInfo.value.mission
// 算法列表
const algorithms = ref([
  { label: '算法A', value: 'algA', level: 0 },
  { label: '算法B', value: 'algB', level: 1 },
  { label: '算法C', value: 'algC', level: 2 },
  { label: '算法D', value: 'algD', level: 3 }
])

// 流程规划与开始计算的控制
const planning = ref(true)
const calculating = ref(false)

// 按钮数据
const buttons = ref([{
  id: 1,
  label: '请选择处理算法',
  parentId: null,
  col: 0,
  row: 0,
  position: { x: 0, y: 0 },
  children: [],
  showExtraBtns: false,
  algorithm: null,
  algorithms: algorithms.value,
}])

provide('plans', buttons)

// 网格布局数据
// 总共只允许三列数据
// 把初始节点填进去
const colRecord = ref([1, 0, 0])
const allowNewCol = ref(true)

// 左侧加载状态控制
const loading = ref(true)



// 状态管理
const selectedAlgorithms = ref({})
const menuVisible = ref({})
const connections = ref([])
const flowContainer = ref()
const buttonRefs = ref([])

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


// 获取初始数据
onMounted(async () => {
  try {
    // 这里替换实际API调用
    await fetchData()
  } finally {
    loading.value = false
  }
})

const fetchData = async () => {
  // 如果已经保存了节点和边的数据，则省略获取数据
  if (nodeData.id && edgeData.id) {
    console.log("跳过获取数据")
    return
  }
  // 如果是从历史文件进入的规划，则应当获取节点和边的数据
  loading.value = true
  // 模拟API请求
  await new Promise(resolve => setTimeout(resolve, 1000))
  Object.assign(nodeData, {
    sNodes: 10,
    dNodes: 5,
    i: 8,
    focus: 15,
    isolate: 3,
    total: 23
  })
  Object.assign(edgeData, {
    concentration: 0.75,
    total: 45
  })

  loading.value = false
}

// 自动布局计算
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

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

    // 子节点布局
    buttons.value.forEach((btn) => {
      if (btn.parentId) {
        const parent = buttons.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
        }
      }

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

      // 直接赋值避免触发响应式更新
      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 hideExtraBtns = (index) => {
  setTimeout(() => { buttons.value[index].showExtraBtns = false }, 200)
}

// 获取按钮中心坐标
const getButtonCenter = (btn) => {
  const index = buttons.value.findIndex(b => b.id === btn.id)
  if (index === -1 || !buttonRefs.value[index]) return { x: 0, y: 0 }

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

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



// 更新连接线
const updateConnections = () => {
  connections.value = []

  // 遍历所有按钮建立连接关系
  buttons.value.forEach(btn => {
    if (btn.parentId) {
      const parent = buttons.value.find(b => b.id === btn.parentId)
      if (!parent) return

      // 获取实际渲染位置
      console.log("redraw line", btn.id, parent.id)
      const start = getButtonCenter(parent)
      const end = getButtonCenter(btn)
      // 除初始节点的并行外，均为父下到子上
      if (btn.row !== 0) {
        if (start.x > 0 && start.y > 0 && end.x > 0 && end.y > 0) {
          connections.value.push({
            source: parent.id,
            target: btn.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 deleteChildren = (btn) => {
  while (btn.children.length !== 0) {
    deleteChildren(btn.children.pop())
  }
  colRecord.value.forEach((head, index) => {
    if (head === btn.id) {
      colRecord.value[index] = 0
    }
  })
  buttons.value = buttons.value.filter(b => b.id !== btn.id)
}

const handleDelete = (btn) => {
  // 处理删除逻辑
  const parent = buttons.value.find(b => b.id === btn.parentId)
  console.log('btn', btn)
  console.log('parent', parent)
  deleteChildren(btn)
  parent.children = parent.children.filter(b => b.id !== btn.id)
  parent.algorithms = algorithms.value.filter(al => al.level >= parent.algorithm.level)
  setTimeout(() => {
    updateConnections()
  }, 200)
};

const handleRight = () => {
  // 处理向右逻辑
  console.log('向右箭头点击');
};

const handleDown = () => {
  // 处理向下逻辑
  console.log('向下箭头点击');
};

const canExpandRight = (btn) => {
  if (!btn.algorithm) {
    return
  }
  let flag = true;
  btn.children.forEach(child => {
    if (child.direction === 'right') {
      flag = false;
    }
  })
  return flag;
}

const canExpandBottom = (btn) => {
  if (!btn.algorithm) {
    return
  }
  let flag = true;
  btn.children.forEach(child => {
    if (child.direction === 'bottom') {
      flag = false;
    }
  })
  return flag;
}


// 添加新按钮
const addButton = (parentIndex, direction) => {
  let parent = buttons.value[parentIndex]
  if (!parent.algorithm) {
    ElMessage.error("必须先选择当前流程算法")
    return
  }
  const newId = Date.now()
  let selfCol = parent.col
  let selfRow = parent.row
  let allowCreate = true
  let findEmptyCol = false
  let allowedAlgorithms = []
  if (direction == 'right') {
    // 创建并行节点时，从父节点的父节点开始
    // 初始节点没有更上一级
    if (parent.parentId) {
      parent = buttons.value.find(b => b.id === parent.parentId)
    }
    colRecord.value.forEach((col, index) => {
      if (findEmptyCol) {
        return
      }
      if (col === 0) {
        selfCol = index
        colRecord.value[index] = newId
        allowedAlgorithms = algorithms.value.filter(al => al.level >= parent.algorithm.level)
        // 创建了计划之后仅允许在同一级算法中修改
        parent.algorithms = algorithms.value.filter(al => al.level === parent.algorithm.level)
        if (index === 2) {
          //已经占满三列，disable所有水平创建按钮
          allowNewCol.value = false
        }
        findEmptyCol = true
        return
      }
      if (index === 2) {
        allowCreate = false
        ElMessage.error('已达到并行上限，禁止继续创建并行流程')
      }
    })
  }
  if (direction == 'bottom') {
    selfRow = selfRow + 1
    // 垂直创建时，如果当前行已有处理流程，则跳过该行
    colRecord.value.forEach((col) => {
      if (col === 0) {
        return
      }
      const colHeadBtn = buttons.value.find(b => b.id === col)
      if (selfRow === colHeadBtn.row) {
        selfRow = selfRow + 1
      }
    })
    allowedAlgorithms = algorithms.value.filter(al => al.level >= parent.algorithm.level)
    // 创建了计划之后仅允许在同一级算法中修改
    parent.algorithms = algorithms.value.filter(al => al.level === parent.algorithm.level)
  }
  if (!allowCreate) {
    //不允许再创建
    return
  }

  const newBtn = {
    id: newId,
    label: '请选择处理算法',
    parentId: parent.id,
    direction,
    col: selfCol,
    row: selfRow,
    position: { ...parent.position },
    children: [],
    algorithm: null,
    algorithms: allowedAlgorithms,
  }

  buttons.value.push(newBtn)
  parent.children.push(newBtn)

  // 添加防抖调用
  // requestAnimationFrame(() => {
  calculateLayout()
  // })
}

// 选择算法
const selectAlgorithm = (index, algorithm) => {
  selectedAlgorithms.value[index] = algorithm.value
  buttons.value[index].label = algorithm.label
  buttons.value[index].algorithm = algorithm
  console.log(buttons.value[index])
  menuVisible.value[index] = false
}


// 限制检查
const checkHorizontalLimit = (btn) => {
  return buttons.value.filter(b =>
    b.row === btn.row
  ).length >= MAX_COLUMNS
}

const checkVerticalLimit = (btn) => {
  return btn.row >= MAX_ROWS
}


const submitPlan = async () => {
  let plans = []
  try {
    buttons.value.forEach(btn => {
      if (!btn.algorithm) {
        throw new Error("no algorithm")
      }

      let planChildren = []
      btn.children.forEach((child) => {
        // 第一行的规划为初始并行，不应存在父子关系
        if (child.row !== 0) {
          planChildren.push({
            col: child.col,
            row: child.row,
          })
        }
      })
      const parent = buttons.value.find(b => b.id === btn.parentId)
      plans.push({
        algorithm: btn.algorithm.value,
        col: btn.col,
        row: btn.row,
        children: planChildren,
        parent: parent ? { col: parent.col, row: parent.row } : null,
      })
    })
  } catch (e) {
    if (e.message === "no algorithm") {
      ElMessage.error("还有流程未选择处理算法")
      return
    } else {
      ElMessage.error(e.response.data.message)
      return
    }
  }
  try {
    const response = await postData('/plan/', { mission: mission.id, plans: plans })
    planning.value = false
    calculating.value = true
    if(response.message === "规划提交成功"){
      ElMessage.success('规划已提交')
    }else if(response.message === "规划已覆盖"){
      ElMessage.warning('该计算任务规划已被覆盖')
    }
    response.data.forEach( p => {
      const btn = buttons.value.find(btn => btn.col === p.col && btn.row === p.row)
      btn.id = p.id
      btn.parentId = p.parentId
    })
    const currentPath = router.currentRoute.value.path;
    const newPath = currentPath.endsWith('/') ? currentPath + 'calculate' : currentPath + '/calculate';
    router.push(newPath)
  } catch (e) {
      ElMessage.error(e.response.data.message)
  }
}

// 初始化
onMounted(() => {
  const resizeObserver = new ResizeObserver(() => {
    calculateLayout()
  })
  if (flowContainer.value) {
    resizeObserver.observe(flowContainer.value)
  }
})

</script>

<style scoped>
.container {
  width: 100%;
  height: 800px;
  display: flex;
  margin: 0 auto;
}

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

.flow-buttons {
  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-buttons {
  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;
  border: solid rgba(66, 144, 256, 0.1);
  background-color: rgba(66, 144, 256, 0.1);
}


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

.delete-btn {
  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;
}

.el-button.is-circle {
  width: 24px;
  height: 24px;
  padding: 0;
}

.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;
}
</style>