<template>
  <div class="page-container">
    <!-- 左侧面板 -->
    <div class="left-panel">
      <div class="custom-tabs-container">
        <div class="tab-header">
          <span class="tab-title">点位清单</span>
        </div>
        <div class="tab-content">
          <v-stage
            ref="stageRef"
            :config="{ width: stageWidth, height: stageHeight }"
            class="konva-container"
          >
            <!-- 点位图层 -->
            <v-layer>
              <template v-for="(point, index) in filterData" :key="point.id">
                <v-group :config="getGroupConfig(point, index)" @click="handlePointClick(point)">
                  <!-- 点位背景矩形 -->
                  <v-rect :config="getRectConfig()" />
                  <!-- 点位图片 -->
                  <v-image :config="getImageConfig(point)" />
                  <!-- 点位名称 -->
                  <v-text :config="getTextConfig(point)" />
                </v-group>
              </template>
            </v-layer>
          </v-stage>
        </div>
      </div>
    </div>
    <!-- 右侧分组容器 -->
    <div class="right-panel">
      <div class="group-container">
        <div v-for="group in groupList" :key="group.id" class="group-item">
          <div
            class="custom-tabs-container2"
            :class="{ 'selected-group': selectedGroupId === group.id }"
            @click="selectGroup(group.id)"
          >
            <div class="tab-header2">
              <template v-if="group.isEditing">
                <el-input
                  v-model="group.groupName"
                  size="small"
                  autofocus
                  @blur="handleTitleBlur(group)"
                  @change="handleTitleBlur(group)"
                  @keyup.enter="handleTitleBlur(group)"
                  class="title-input2"
                />
              </template>
              <template v-else>
                <span class="tab-title2" @click="group.isEditing = true">
                  {{ group.groupName }}
                </span>
              </template>
              <div class="del-group-btn" v-if="groupList.length > 1" @click="removeGroup(group.id)">
                删除分组
              </div>
            </div>
            <div class="tab-content2"  >
              <!-- 分组内容 - 使用 vue-konva 渲染点位 -->
              <v-stage :config="{ width: 600, height: 220,}" class="right-konva-container">
                <v-layer>
                  <template v-for="(pointId, index) in group.pointIds" :key="pointId">
                    <v-group
                      :config="getGroupPointConfig(pointId, index)"
                      @click="handleGroupPointClick(group.id, pointId)"
                    >
                      <!-- 点位背景矩形 -->
                      <v-rect :config="getGroupRectConfig()" />
                      <!-- 点位图片 -->
                      <v-image :config="getGroupImageConfig(pointId)" />
                      <!-- 点位名称 -->
                      <v-text :config="getGroupTextConfig(pointId)" />
                    </v-group>
                  </template>
                </v-layer>
              </v-stage>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
  <!-- 底部按钮区 -->
  <div class="bottom-btn">
    <el-button @click="submit">
      <el-icon>
        <Check />
      </el-icon>
      确 定
    </el-button>
    <el-button @click="cancel">
      <el-icon>
        <Close />
      </el-icon>
      取 消
    </el-button>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, onMounted, watch, nextTick } from 'vue'
import { useRoute } from 'vue-router'
import * as MachineryApi from '@/api/dv/technology/index'
import * as PointApi from '@/api/dv/spm/index'
import VueKonva from 'vue-konva'
import { Check, Close } from '@element-plus/icons-vue'
import * as SopApi from '@/api/sop/index'
import * as SopPointGroup from '@/api/sop/sopPointGroup'
import * as SopPoint from  '@/api/sop/sopPoint'

const message = useMessage() // 消息弹窗
const { t } = useI18n() // 国际化
const boundPointIds = ref<number[]>([])
const allPoints = ref<any[]>([])
const filterData = ref<any[]>([])
const stageRef = ref()
const stageWidth = 800
const stageHeight = 700
// 左侧点位配置
const rectWidth = 60 // 增大宽度
const rectHeight = 100 // 增大高度，为标题预留空间
const rectGapX = 5 // 横向间距加大
const rectGapY = 10 // 纵向间距加大

// 右侧分组内点位的尺寸配置
const groupPointWidth = 40
const groupPointHeight = 60
const groupPointGapX = 10
const groupPointGapY = 10

const route = useRoute()
const router=useRouter()
const props = defineProps({
  groupAdded: Boolean
})
// 记录当前选中的分组ID（高亮分组）
const selectedGroupId = ref<number | null>(null)
const groupList = ref([])


// 移除 watch 中的异步调用，改为同步添加本地分组
watch(
  () => props.groupAdded,
  async (newVal) => {
    if (newVal) {
      try {
        const defaultName = `目标点位${groupList.value.length + 1}`
        const response = await SopPointGroup.insertSopGroup({
          sopId: route.query.sopId,
          groupName: defaultName
        })

        if (response) {
          groupList.value.push({
            id: response,
            sopId: route.query.sopId,
            groupName: defaultName,
            isEditing: false,
            pointIds: [] as number[]
          })
          console.log('新增分组成功:', groupList.value)
        } else {
          console.warn('新增分组失败，接口未返回 ID')
        }
      } catch (error) {
        console.error('新增分组失败:', error)
      }
    }
  }
)


// 放置filterData数据移动之后丢失 映射一个齐全的隔离点数据方便渲染右侧
const pointMap = computed(() => {
  const map = new Map<number, any>()
  allPoints.value.forEach((point) => {
    map.set(point.id, point)
  })
  return map
})

// 右侧标题修改
const handleTitleBlur = async (group: (typeof groupList.value)[0]) => {
  if (!group.groupName.trim()) {
    group.groupName = `目标点位${group.id}`
  }

  try {
    // 直接走更新接口（因为新增时已经通过监听完成）
    const updateData = {
      id: group.id,
      sopId: route.query.sopId,
      groupName: group.groupName
    }
    await SopPointGroup.updateSopGroup(updateData)
    console.log('更新分组成功:', group.id)
  } catch (error) {
    console.error('更新分组失败:', error)
  }

  group.isEditing = false
}

// 移除分组
const removeGroup = async (groupId: number) => {
  try {
    // 调用删除分组接口
    await SopPointGroup.deleteSopGroupList(groupId)

    // 接口调用成功后，从本地列表中移除
    groupList.value = groupList.value.filter((group) => group.id !== groupId)

    // 如果删除的是当前选中分组，自动选中第一个分组
    if (selectedGroupId.value === groupId) {
      selectedGroupId.value = groupList.value.length > 0 ? groupList.value[0].id : null
    }

    // 更新过滤数据
    updateFilterData()

  } catch (error) {

  }
}
// 选中分组
const selectGroup = (groupId: number) => {
  selectedGroupId.value = groupId
  console.log(groupId,'groupId')
}
// 左侧点位点击：添加到当前高亮分组
const handlePointClick = (point) => {
  if (!selectedGroupId.value) {
    console.warn('没有选中任何分组')
    return
  }
  const group = groupList.value.find(g => g.id === selectedGroupId.value)
  if (!group) return

  if (!group.pointIds.includes(point.id)) {
    group.pointIds.push(point.id)
    updateFilterData(true)
  } else {
    console.log('点位已存在于分组中')
  }
}



const imageCache = new Map<string, HTMLImageElement>()

// 计算左侧每个点位的坐标（自动换行）
const getGroupConfig = (point: any, index: number) => {
  // 每行可容纳的点位数量（基于舞台宽度和间距计算）
  const itemsPerRow = Math.floor(stageWidth / (rectWidth + rectGapX))
  const row = Math.floor(index / itemsPerRow)
  const col = index % itemsPerRow
  return {
    x: col * (rectWidth + rectGapX) + 5, // 左侧预留20px边距
    y: row * (rectHeight + rectGapY) + 5 // 顶部预留20px边距
  }
}

// 左侧背景矩形配置（与点位尺寸匹配）
const getRectConfig = () => ({
  width: rectWidth,
  height: rectHeight
})

// 左侧图标配置（居中显示在矩形上半部分）
const getImageConfig = (point: any) => {
  let img = imageCache.get(point.pointIcon)
  if (!img) {
    img = new window.Image()
    img.src = point.pointIcon || '' // 空值处理
    img.onerror = () => {
      console.warn(`图标加载失败: ${point.pointIcon}`)
    }
    imageCache.set(point.pointIcon, img)
  }
  return {
    image: img,
    x: (rectWidth - 50) / 2, // 图标水平居中（图标宽40）
    y: 10, // 距离顶部10px
    width: 50,
    height: 50
  }
}

// 左侧隔离点标题配置（显示在图标正下方，矩形底部）
const getTextConfig = (point: any) => ({
  x: rectWidth - 62, // 水平居中（基于矩形宽度）
  y: rectHeight - 35, // 距离底部20px（确保在图标下方）
  text: point.pointName || '未命名', // 空值处理
  fontSize: 12, // 适配尺寸
  fill: '#333',
  align: 'center', // 文字居中
  verticalAlign: 'middle',
  width: rectWidth, // 限制文字宽度，避免溢出
  wrap: 'word' // 自动换行
})

// 右侧分组内点位的 group 配置
const getGroupPointConfig = (pointId: number, index: number) => {
  const itemsPerRow = Math.floor(380 / (groupPointWidth + groupPointGapX))
  const row = Math.floor(index / itemsPerRow)
  const col = index % itemsPerRow
  return {
    x: col * (groupPointWidth + groupPointGapX) + 5,
    y: row * (groupPointHeight + groupPointGapY) + 5
  }
}

// 右侧分组内点位的矩形配置
const getGroupRectConfig = () => ({
  width: groupPointWidth,
  height: groupPointHeight,
  shadowBlur: 1
})

// 右侧分组内点位的图片配置
const getGroupImageConfig = (pointId: number) => {
  const point = pointMap.value.get(pointId)
  if (!point) return {}

  let img = imageCache.get(point.pointIcon)
  if (!img) {
    img = new window.Image()
    img.src = point.pointIcon || ''
    imageCache.set(point.pointIcon, img)
  }

  return {
    image: img,
    x: (groupPointWidth - 30) / 2,
    y: 5,
    width: 30,
    height: 30
  }
}

// 右侧分组内点位的文本配置
const getGroupTextConfig = (pointId: number) => {
  const point = pointMap.value.get(pointId)
  return {
    x: 0,
    y: groupPointHeight - 20,
    text: point ? point.pointName : '未知',
    fontSize: 10,
    // fill: '#333',
    align: 'center',
    verticalAlign: 'middle',
    width: groupPointWidth,
    wrap: 'word'
  }
}

// 右侧分组内点位点击：从分组移除（回归左侧）
const handleGroupPointClick = async (groupId: number, pointId: number) => {
  removePointFromGroup(groupId, pointId)
  await updateFilterData(true)
}

// 从分组中移除点位的通用方法
const removePointFromGroup = (groupId: number, pointId: number) => {
  const group = groupList.value.find((g) => g.id === groupId)
  if (!group) return
  group.pointIds = group.pointIds.filter((id) => id !== pointId)
}
// 更新filterData
const updateFilterData = async (skipReload = false) => {
  if (!skipReload) {
    try {
      const groupData = await SopApi.selectSopById(route.query.sopId)

      if (groupData?.sopPointsList?.length > 0) {
        groupList.value.forEach(group => group.pointIds = [])

        groupData.sopPointsList.forEach((sopPoint: any) => {
          const group = groupList.value.find(g => g.id === sopPoint.groupId)
          if (group && !group.pointIds.includes(sopPoint.pointId)) {
            group.pointIds.push(sopPoint.pointId)
          }
        })
      }
    } catch (error) {
      console.error('接口失败，回退本地计算')
    }
  }

  // 用当前 groupList 计算 filterData
  filterData.value = allPoints.value.filter((point: any) => {
    const isIncluded = boundPointIds.value.includes(point.id)
    const inAnyGroup = groupList.value.some((group) => group.pointIds.includes(point.id))
    return isIncluded && !inAnyGroup
  })
}

// 初始化数据
const getOtherList = async () => {
  try {
    // 获取工艺绑定过的隔离点
    const data = await MachineryApi.getTechnologyInfo(route.query.machineryId)
    boundPointIds.value = data.pointIdList || []

    // 获取所有隔离点
    const pointData = await PointApi.getIsIsolationPointPage({ pageNo: 1, pageSize: -1 })
    allPoints.value = pointData.list || []

    // 先尝试获取sop点位分组
    const sopGroupData = await SopPointGroup.getSopGroupList({
      pageNo: 1,
      pageSize: -1,
      sopId: route.query.sopId // 传递sopId参数
    })

    console.log(sopGroupData, 'sopGroupData')

    if (sopGroupData && sopGroupData.length > 0) {
      // 如果能获取到分组数据，直接使用
      groupList.value = sopGroupData.map((group: any) => ({
        id: group.id,
        sopId: group.sopId,
        groupName: group.groupName,
        isEditing: false,
        pointIds: []
      }))
    } else {
      // 如果没有分组数据，调用SOP接口获取默认分组
      const groupData = await SopApi.selectSopById(route.query.sopId)
      console.log(groupData, 'groupData')
      groupList.value = groupData.sopGroupList.map((group: any, index: number) => ({
        id: group.id,
        sopId: group.sopId,
        groupName: group.groupName,
        isEditing: false,
        pointIds: []
      }))
    }

    // 筛选出真正绑定的点位
    updateFilterData()
  } catch (error) {
    console.error('获取数据失败:', error)
    filterData.value = []
  }
}

watch(
  filterData,
  async () => {
    await nextTick()
  },
  { deep: true }
)

onMounted(async () => {
  await getOtherList()
})
// 保存更新的信息
const submit = async () => {
  try {
    const detailSop = await SopApi.selectSopById(route.query.sopId)
    const oldPoints = detailSop.sopPointsList || []

    const oldKeySet = new Set(
      oldPoints.map(item => `${item.groupId}_${item.pointId}`)
    )

    // 1. 生成当前用户操作的点位集合（newPoints）
    const allCurrentPoints = []
    groupList.value.forEach(group => {
      group.pointIds.forEach(pointId => {
        allCurrentPoints.push({
          sopId: route.query.sopId,
          groupId: group.id,
          pointId: pointId
        })
      })
    })

    const newKeySet = new Set(
      allCurrentPoints.map(item => `${item.groupId}_${item.pointId}`)
    )

    // 2. 计算出旧数据中已被移除的点位（需要删除）
    const toDeleteList = oldPoints.filter(item => {
      const key = `${item.groupId}_${item.pointId}`
      return !newKeySet.has(key)
    })

    // 3. 删除接口
    if (toDeleteList.length > 0) {
      const deleteIds = toDeleteList.map(item => item.id)
      await SopPoint.deleteSopPointsList(deleteIds)
      message.success('保存成功')
      console.log('已删除点位:', deleteIds)
    }

    // ✅ 4. 从 allCurrentPoints 中剔除掉旧数据中已存在的内容，仅新增
    const oldKeySetAfterDelete = new Set(
      oldPoints.map(item => `${item.groupId}_${item.pointId}`)
    )
    const newOnlyInsertPoints = allCurrentPoints.filter(item => {
      const key = `${item.groupId}_${item.pointId}`
      return !oldKeySetAfterDelete.has(key)
    })

    if (newOnlyInsertPoints.length > 0) {
      await SopPoint.insertSopPoints(newOnlyInsertPoints)
      message.success(t('common.createSuccess'))
      console.log('新增成功:', newOnlyInsertPoints)
    } else {
      console.log('无新增点位')
    }
  } catch (error) {
    console.error('提交失败:', error)
  }
}

const cancel = () => {
  router.push({
    path:'/sopm/sopm/sop/UpdateSop',
    query:{
      id:route.query.sopId,
      type:route.query.type,
    }
  })
}
</script>
<style scoped lang="scss">
// 外层页面容器：占满整个可视区域
.page-container {
  height: 100vh; // 占满屏幕高度
  display: flex;
}

// 左侧面板
.left-panel {
  flex: 20;
}

// 右侧面板
.right-panel {
  flex: 4;
  margin-left: 10px;
  min-width: 600px;
}

// 右侧分组容器
.group-container {
  display: flex;
  flex-direction: column; // 纵向堆叠
  gap: 20px;
  height: 100%; // 高度占满右侧面板
  overflow-y: auto; // 超出高度时滚动
  padding-right: 10px; // 预留滚动条空间
  box-sizing: border-box;
}

// 单个分组
.group-item {
  width: 100%;
  // 强制分组高度一致（可选）
  min-height: 300px;
}

// 左侧容器样式
.custom-tabs-container {
  border: 1px solid #dcdfe6;
  border-radius: 4px;
  height: 100%; // 占满左侧面板高度
  display: flex;
  flex-direction: column;
  box-sizing: border-box; // 包含 border 计算高度
}

.tab-header {
  background-color: #f5f7fa;
  border-bottom: 1px solid #dcdfe6;
  padding: 12px 20px;
  border-radius: 4px 4px 0 0;
}

.tab-content {
  padding: 20px;
  background-color: #fff;
  border-radius: 0 0 4px 4px;
  flex: 1; // 占满剩余高度
  overflow-y: auto; // 内容超出时滚动
}

// 右侧分组样式
.custom-tabs-container2 {
  border: 1px solid #e4e7ed;
  border-radius: 6px;
  height: 300px; // 固定高度
  min-width: 400px;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  box-sizing: border-box;
}

.tab-header2 {
  padding: 8px 16px;
  background-color: #f5f7fa;
  border-bottom: 1px solid #e4e7ed;
  display: flex;
  justify-content: space-between;
  align-items: center; // 垂直居中
  gap: 10px;
}

// 底部按钮区
.bottom-btn {
  display: flex;
  gap: 10px; // 按钮间距
  justify-content: flex-end;
  padding-top: 10px;
  border-top: 1px solid #eee; // 分隔线
}

// 其他样式保持不变（标题、输入框、删除按钮等）
.tab-title2 {
  cursor: pointer;
  transition: color 0.2s;
}

.tab-title2:hover {
  color: #409eff;
}

.title-input2 {
  width: 120px;
}

.del-group-btn {
  width: 70px;
  height: 30px;
  border: 1px solid #ccc;
  border-radius: 6px;
  text-align: center;
  line-height: 30px;
  cursor: pointer;
  font-size: 12px; // 适配按钮大小
}

.konva-container {
  width: 100%;
  height: 700px;
  background-color: #fff;
  border: 1px dashed red; // 可视化调试
}

//选中右侧的分组高亮
.selected-group {
  border: 2px solid #409eff !important;
  box-shadow: 0 0 8px #409eff33;
}

//右侧隔离点渲染
.right-konva-container {
  width: 100%;
  height: 220px;
  //background-color: #fafafa;
  //border-radius: 4px;
  margin: 10px;
}
</style>
