<template v-if="renderKey">
  <div class="mapdata-container">
    <v-stage
      ref="stageRef"
      :config="stageConfig"
      @dragend="handleStageDragEnd"
    >
      <v-layer ref="layerRef">
        <!-- 网格 -->
        <v-line
          v-for="(line, index) in gridLines"
          :key="`grid-${index}`"
          :config="line"
        />

        <!-- 背景图片 -->
        <v-image
          v-if="backgroundImage"
          :config="backgroundImage"
        />

        <!-- 右侧盒子 -->
        <v-rect
          :config="rightBoxConfig"
        />
        <v-text
          :config="rightBoxTextConfig"
        />

        <!-- 隔离点 -->
        <v-group
          v-for="point in renderedPoints"
          :key="`point-${point.id}`"
          :config="point.groupConfig"
          @dragend="(e) => handlePointDragEnd(e, point)"
        >
          <v-rect :config="point.bgRectConfig" />
          <v-rect :config="point.rectConfig" />
          <v-image :config="point.imageConfig" />
          <v-text :config="point.textConfig" />
        </v-group>

        <!-- 右侧隔离点 -->
        <v-group
          v-for="(rightPoint, index) in rightPoints"
          :key="`right-point-${rightPoint.pointId}`"
          :config="getRightPointConfig(rightPoint, index)"
          @dragend="(e) => handleRightPointDragEnd(e, rightPoint)"
        >
          <v-rect :config="getRightPointRectConfig()" />
          <v-image :config="getRightPointImageConfig(rightPoint)" />
          <v-text :config="getRightPointTextConfig(rightPoint)" />
        </v-group>
      </v-layer>
    </v-stage>

    <div class="action-bar">
      <el-button
        v-no-more-click
        @click="handleSave"
        type="primary"
        :icon="Check"
        class="action-btn save-btn"
      >
        保存配置
      </el-button>

      <el-button
        v-no-more-click
        @click="handleReset"
        type="warning"
        :icon="RefreshLeft"
        class="action-btn reset-btn"
      >
        重置
      </el-button>


    </div>
  </div>
</template>

<script lang="ts" setup>
import {
  Check,
  RefreshLeft
} from '@element-plus/icons-vue'
import { ref, reactive, computed, onMounted, nextTick } from 'vue'
import { useRoute } from 'vue-router'
import {  ElMessageBox } from 'element-plus'
import * as LotoStationApi from '@/api/dv/lotoStation/index'
import * as SegregationPointApi from '@/api/dv/spm/index'
import * as MapPointApi from '@/api/basic/mappoint/index'
import * as MapConfigApi from '@/api/basic/mapconfig/index'
import {updateMapPointList} from "@/api/basic/mappoint/index";

defineOptions({ name: 'MapData' })

const route = useRoute()
const message = useMessage()

// 响应式数据
const stageRef = ref()
const layerRef = ref()

// 地图相关数据
const mapData = reactive({
  form: {} as any,
  originData: null as any,
  filterData: null as any,
  leftPoints: [] as any[],
  orgLeftPoints: [] as any[],
  rightPoints: [] as any[],
  orgRightPoints: [] as any[],
  groups: [] as any[],
  bindingPointIds: [] as string[],
  unbindPointIds: [] as string[],
  isSave: true,
  isInitialized: false,
  imageUrl: '',
  width: 0,
  height: 0,
  x: 0,
  y: 0,
  mapId: null as number | null,
  mapType: 2,
  pointList: null as any[] | null,
  newbindingPoints: [] as any[],
  newmovePoints: [] as any[],
  newunbindingPoints: [] as any[]
})

// 舞台配置
const stageConfig = reactive({
  width: 1600,
  height: 860,
  draggable: false
})

// 网格线配置
const gridLines = computed(() => {
  const lines = []
  const cellWidth = 50
  const cellHeight = 50
  const width = 1600
  const height = 860

  // 竖线
  for (let i = 0; i <= width; i += cellWidth) {
    lines.push({
      points: [i, 0, i, height],
      stroke: '#e0e0e0',
      strokeWidth: 1
    })
  }

  // 横线
  for (let j = 0; j <= height; j += cellHeight) {
    lines.push({
      points: [0, j, width, j],
      stroke: '#e0e0e0',
      strokeWidth: 1
    })
  }

  return lines
})

// 背景图片配置
const backgroundImage = computed(() => {
  console.log(mapData,'背景图')

  // 创建图片对象并设置src
  const img = new Image()
  img.src = mapData.imageUrl
  return {
    x: mapData.x,
    y: mapData.y,
    width: mapData.width,
    height: mapData.height,
    image: img,
    draggable: false
  }
})

// 右侧盒子配置
const rightBoxConfig = {
  x: 1100,
  y: 15,
  width: 200,
  height: 800,
  cornerRadius: 5,
  stroke: 'black',
  strokeWidth: 2,
  fill: 'white'
}

const rightBoxTextConfig = {
  x: 1110,
  y: 20,
  text: '未绑定锁定站的隔离点数据',
  fontSize: 15,
  fill: 'black'
}

// 渲染的点位数据
const renderedPoints = computed(() => {
  if (!mapData.pointList) return []

  return mapData.pointList.map((item: any) => {
    const x = item.x * 50
    const y = item.y * 50
    const labelText = item.entityName
    const img = new Image();
    img.src = item.pointIcon || '';
    return {
      id: item.id,
      pointId: item.entityId,
      entityName: item.entityName,
      originalData: item,
      groupConfig: {
        x: x,
        y: y,
        draggable: true
      },
      bgRectConfig: {
        x: -1,
        y: -5,
        width: 50,
        height: 78,
        cornerRadius: 5,
        stroke: 'white',
        strokeWidth: 2,
        fill: 'white'
      },
      rectConfig: {
        x: 1,
        y: -1,
        width: 45,
        height: 70,
        cornerRadius: 5,
        stroke: 'red',
        strokeWidth: 2,
        fill: 'white'
      },

      imageConfig: {
        x: 1,
        y: 0,
        width: 45,
        height: 45,
        image: img
      },
      textConfig: {
        x: 8,
        y: 50,
        fontSize: 17,
        text: labelText,
        fontFamily: 'Calibri',
        fill: 'red'
      }
    }
  })
})

// 获取右侧点位配置
const getRightPointConfig = (point: any, index: number) => {
  const boxX = 1100
  const boxY = 15
  const padding = 10
  const pointWidth = 50
  const pointHeight = 70

  const col = index % 3
  const row = Math.floor(index / 3)

  const x = boxX + padding + col * (pointWidth + padding)
  const y = boxY + padding + row * (pointHeight + padding) + 14

  return {
    x: x,
    y: y,
    draggable: true
  }
}

const getRightPointRectConfig = () => ({
  x: 0,
  y: 0,
  width: 50,
  height: 70,
  cornerRadius: 5,
  stroke: 'red',
  strokeWidth: 2,
  fill: 'white'
})

const getRightPointImageConfig = (point: any) => ({
  x: 1,
  y: 5,
  width: 50,
  height: 50,
  image: new Image()
})

const getRightPointTextConfig = (point: any) => ({
  x: 12,
  y: 53,
  text: point.pointName,
  fontSize: 12,
  fill: 'red'
})

// 获取作业区域信息
const getInfo = async () => {
  try {
    const lotoId = route.query.id as string
    const response = await LotoStationApi.selectIsLotoStationById(lotoId)
    console.log(response, '作业区域信息')

    mapData.form = response
    mapData.mapId = response.mapId

    // 获取底图信息
    const mapResponse = await MapConfigApi.selectIsMapById(response.mapId)
    console.log(mapResponse, '获取底图')

    mapData.imageUrl = mapResponse.imageUrl
    mapData.width = mapResponse.width
    mapData.height = mapResponse.height
    mapData.x = mapResponse.x
    mapData.y = mapResponse.y


    // 获取地图JSON数据
    const mapJsonResponse = await LotoStationApi.selectLotoMapById(lotoId, '', '')
    console.log(mapJsonResponse, '作业区域预览接口调用')

    mapData.form.map = mapJsonResponse
    mapData.filterData = mapJsonResponse
    if(mapResponse.pointList){
      mapData.pointList = mapResponse.pointList
    }else {
      mapData.pointList = mapJsonResponse
    }

    // 获取隔离点数据
    const pointData = {
      pageNo: 1,
      pageSize: -1,
      lotoId: route.query.id
    }

    const pointResponse = await SegregationPointApi.getIsIsolationPointPage(pointData)
    const data1 = pointResponse.list
    const data2 = mapData.filterData

    console.log(data1, '该柜子或地图所有点', data2, '该柜子里json拿到的点位')

    // 创建Set来存储已存在的pointId
    const data2PointIds = new Set(data2.map((item: any) => item.pointId))
    const pointListIds = new Set(mapData.pointList?.map((item: any) => item.pointId) || [])

    // 过滤掉已存在的点位
    const filterData = data1.filter(
      (item: any) => !data2PointIds.has(item.pointId) && !pointListIds.has(item.pointId)
    )

    console.log(filterData, 'filterData-交叉数据')

    mapData.orgLeftPoints = pointResponse.list.map((item: any) => ({
      pointId: item.pointId,
      entityId: item.pointId,
      entityName: item.pointName,
      pointName: item.pointName,
      remark: item.remark,
      prePointId: item.prePointId,
      pointType: item.pointType,
      pointTypeName: item.pointTypeName,
      powerType: item.powerType,
      powerTypeName: item.powerTypeName,
      pointIcon: item.pointIcon,
      status: false,
      pointPicture: item.pointPicture,
      mapImg: null
    }))

    if (mapJsonResponse) {
      try {
        mapData.originData = JSON.stringify(mapJsonResponse, null, 4)
      } catch (err) {
        console.error('JSON解析错误:', err)
      }
    }
  } catch (error) {
    console.error('获取信息失败:', error)
    message.error('获取信息失败')
  }
}

// 获取未绑定的所有隔离点
const getIsIsolationPointPage = async () => {
  try {
    const data = {
      pageNo: 1,
      pageSize: -1,
      lotoId: 0
    }

    const response = await SegregationPointApi.getIsIsolationPointPage(data)

    mapData.rightPoints = response.list.map((item: any) => ({
      entityId: item.pointId,
      entityName: item.pointName,
      pointId: item.pointId,
      pointName: item.pointName,
      remark: item.remark,
      prePointId: item.prePointId,
      pointType: item.pointType,
      pointTypeName: item.pointTypeName,
      powerType: item.powerType,
      powerTypeName: item.powerTypeName,
      pointIcon: item.pointIcon,
      status: false,
      pointPicture: item.pointPicture,
      mapImg: null,
      mapId: mapData.mapId,
      mapType: mapData.mapType
    }))

    mapData.orgRightPoints = JSON.parse(JSON.stringify(mapData.rightPoints))
  } catch (error) {
    console.error('获取隔离点失败:', error)
    message.error('获取隔离点失败')
  }
}

// 重置功能
const renderKey = ref(0)
const handleReset = async () => {
  try {
    // 暂时隐藏点位，等数据重建后再显示
    renderKey.value = 0

    // 清空数据
    mapData.leftPoints = []
    mapData.rightPoints = []
    mapData.pointList = []
    mapData.bindingPointIds = []
    mapData.unbindPointIds = []
    mapData.originData = null

    // 重新加载所有地图信息
    await getInfo()
    await getIsIsolationPointPage()

    // 延迟一点恢复渲染（确保 dom 更新完）
    await nextTick()
    renderKey.value = 1

    message.success('已重置为初始状态')
  } catch (error) {
    console.error('重置失败:', error)
    message.error('重置失败，请稍后重试')
  }
}



// 保存功能
const handleSave = async () => {
  try {
    await ElMessageBox.confirm('请确认是否保存修改内容', '提示', {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning'
    })

    // 校验数据格式
    if (!isValidJson(mapData.originData)) {
      message.error('地图数据格式不正确，请输入有效的 JSON 格式!')
      return
    }

    const mapDataString = typeof mapData.originData === 'string'
      ? mapData.originData
      : JSON.stringify(mapData.originData)

    const formData = {
      ...mapData.form,
      map: mapDataString
    }

    console.log(formData, 'map')

    // 更新作业区域地图
    await LotoStationApi.updateLoto(formData)
    message.success('保存成功!')

    // 更新地图点位
    const dataMap = {
      bindingPoints: mapData.leftPoints,
      movePoints: JSON.parse(mapData.originData),
      unbindingPoints: mapData.rightPoints
    }

    console.log(dataMap, '先拿到数据看看再说')
    await MapPointApi.updateMapPointList(dataMap)
    console.log('拿到的新绑定数据')

    // 更新绑定关系
    const bindingData = {
      bindingPointIds: mapData.bindingPointIds,
      lotoId: route.query.id,
      unbindPointIds: mapData.unbindPointIds
    }

    console.log(bindingData, '解绑与绑定数据参数')
    await LotoStationApi.updatePointsBindingLoto(bindingData)
    console.log('解绑接口返回值')

    mapData.bindingPointIds = []
    mapData.unbindPointIds = []

    // 重新获取信息
    await getInfo()
  } catch (error) {
    if (error !== 'cancel') {
      console.error('保存失败:', error)
      message.error('保存失败')
    }
  }
}

// 校验字符串是否为有效的 JSON
const isValidJson = (str: any): boolean => {
  try {
    JSON.parse(str)
    return true
  } catch (e) {
    return false
  }
}

// 处理点位拖拽结束
const handlePointDragEnd = (e: any, point: any) => {
  const group = e.target
  const groupPos = group.getAbsolutePosition()

  // 定义区域范围
  const rightBoxBounds = {
    x: 1100,
    y: 15,
    width: 200,
    height: 800
  }

  const cabinetBounds = {
    x: 330,
    y: 10,
    width: 500,
    height: 790
  }

  const isInCabinet =
    groupPos.x >= cabinetBounds.x &&
    groupPos.x <= cabinetBounds.x + cabinetBounds.width &&
    groupPos.y >= cabinetBounds.y &&
    groupPos.y <= cabinetBounds.y + cabinetBounds.height

  const isInRightBox =
    groupPos.x >= rightBoxBounds.x &&
    groupPos.x <= rightBoxBounds.x + rightBoxBounds.width &&
    groupPos.y >= rightBoxBounds.y &&
    groupPos.y <= rightBoxBounds.y + rightBoxBounds.height

  // 处理拖拽逻辑
  if (isInRightBox) {
    moveToRightBox(point, groupPos)
  } else if (!isInCabinet && !isInRightBox) {
    updatePointPosition(point, groupPos)
  } else if (isInCabinet && !isInRightBox) {
    updatePointPosition(point, groupPos)
  }
}

// 处理右侧点位拖拽结束
const handleRightPointDragEnd = (e: any, point: any) => {
  const group = e.target
  const groupPos = group.getAbsolutePosition()

  const gridX = 50
  const gridY = 50

  const snappedX = Math.round(groupPos.x / gridX) * gridX
  const snappedY = Math.round(groupPos.y / gridY) * gridY

  group.x(snappedX)
  group.y(snappedY)

  const row = Math.floor(snappedY / gridY)
  const col = Math.floor(snappedX / gridX)

  const rightBoxBounds = {
    x: 1100,
    y: 15,
    width: 200,
    height: 800
  }

  const cabinetBounds = {
    x: 330,
    y: 10,
    width: 500,
    height: 790
  }

  if (
    snappedX >= rightBoxBounds.x &&
    snappedX <= rightBoxBounds.x + rightBoxBounds.width &&
    snappedY >= rightBoxBounds.y &&
    snappedY <= rightBoxBounds.y + rightBoxBounds.height
  ) {
    // 进入右侧盒子区域
    handleRightBoxEnter(point, col, row)
  } else if (
    snappedX < rightBoxBounds.x ||
    snappedX > rightBoxBounds.x + rightBoxBounds.width ||
    snappedY < rightBoxBounds.y ||
    snappedY > rightBoxBounds.y + rightBoxBounds.height
  ) {
    // 进入物资柜区域
    handleCabinetEnter(point, col, row)
  }
}

// 移动到右侧盒子
const moveToRightBox = (point: any, groupPos: any) => {
  if (!mapData.rightPoints.find((p) => p.entityName === point.entityName)) {
    mapData.rightPoints.push(point)
    mapData.unbindPointIds.push(point.pointId)

    const bindingIndex = mapData.bindingPointIds.indexOf(point.pointId)
    if (bindingIndex !== -1) {
      mapData.bindingPointIds.splice(bindingIndex, 1)
    }
  }
}

// 更新点位位置
const updatePointPosition = (point: any, groupPos: any) => {
  const newCol = Math.round(groupPos.y / 50)
  const newRow = Math.round(groupPos.x / 50)

  const maxCols = Math.floor(860 / 50) - 1
  const maxRows = Math.floor(1200 / 50) - 1

  const boundedCol = Math.max(0, Math.min(newCol, maxCols))
  const boundedRow = Math.max(0, Math.min(newRow, maxRows))

  const updatedPosition = {
    row: boundedRow,
    col: boundedCol,
    id: point.id,
    pointId: point.pointId,
    entityId: point.entityId,
    entityName: point.entityName,
    pointName: point.entityName,
    mapId: mapData.mapId,
    mapType: mapData.mapType,
    x: boundedRow,
    y: boundedCol,
    pointType: point.pointType,
    pointTypeName: point.pointTypeName,
    powerType: point.powerType,
    powerTypeName: point.powerTypeName,
    state: point.state,
    pointIcon: point.pointIcon,
    pointPicture: point.pointPicture,
    mapImg: point.mapImg
  }

  // 更新点位数据
  const positions = JSON.parse(mapData.originData || '[]')
  const index = positions.findIndex((item: any) => item.pointId === point.pointId)

  if (index !== -1) {
    positions[index] = updatedPosition
  } else {
    positions.push(updatedPosition)
  }

  mapData.originData = JSON.stringify(positions, null, 4)
}

// 处理右侧盒子进入
const handleRightBoxEnter = (point: any, col: number, row: number) => {
  point.row = col
  point.col = row
  point.x = col
  point.y = row

  const positions = JSON.parse(mapData.originData || '[]')
  const index = positions.findIndex((item: any) => item.pointId === point.pointId)

  if (index !== -1) {
    positions.splice(index, 1)
  }

  mapData.originData = JSON.stringify(positions, null, 4)
  mapData.bindingPointIds = mapData.bindingPointIds.filter((id) => id !== point.pointId)
  mapData.unbindPointIds.push(point.pointId)
  mapData.rightPoints.push(point)
}

// 处理物资柜进入
const handleCabinetEnter = (point: any, col: number, row: number) => {
  point.row = col
  point.col = row
  point.x = col
  point.y = row

  const updatedPointData = {
    row: col,
    col: row,
    pointId: point.pointId,
    entityId: point.entityId,
    entityName: point.entityName,
    pointName: point.pointName,
    remark: point.remark,
    prePointId: point.prePointId,
    pointType: point.pointType,
    pointTypeName: point.pointTypeName,
    powerType: point.powerType,
    powerTypeName: point.powerTypeName,
    state: point.status,
    pointIcon: point.pointIcon,
    pointPicture: point.pointPicture,
    mapImg: null
  }

  const positions = JSON.parse(mapData.originData || '[]')
  const index = positions.findIndex((item: any) => item.pointId === point.pointId)

  if (index === -1) {
    positions.push(updatedPointData)
    mapData.originData = JSON.stringify(positions, null, 4)
  }

  mapData.bindingPointIds.push(point.pointId)
  mapData.rightPoints = mapData.rightPoints.filter((item) => item.pointId !== point.pointId)
  mapData.leftPoints.push(point)
}



// 组件挂载
onMounted(async () => {
  await nextTick()
  await getInfo()
  await getIsIsolationPointPage()
})
</script>

<style scoped lang="scss">
.mapdata-container {
  width: 100%;
  height: 100%;
  display: flex;

}

/* 按钮样式 */
.action-btn {
  height: 44px;
  min-width: 120px;
  font-size: 16px;
  font-weight: bold;
  border-radius: 8px !important;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
  transition: all 0.2s;
}

.save-btn {
  background: linear-gradient(135deg, #409EFF, #3375e0);
  border: none;
  margin: 10px 0px 10px 10px;

}

.reset-btn {
  background: linear-gradient(135deg, #E6A23C, #d18f2c);
  border: none;
  color: white;
}

.action-btn:hover {
  transform: translateY(-2px);
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15);
}

.action-btn:active {
  transform: translateY(0);
}
</style>
