<template>
  <div class="edit-map-page" @wheel="handleWheel">
    <div class="top-tool">
      <div class="top-tool-list">
        <div v-for="item in state.topToolList" :key="item.switchType" class="top-tool-item">
          <el-popover
            placement="bottom"
            :width="170"
            trigger="click"
            v-if="item.switchType === 'move' || item.switchType === 'revolve'"
            :disabled="state.currentItemIndex === -1"
          >
            <template #reference>
              <div
                class="tool-item"
                :class="
                  toolbarSwitchType === item.switchType
                    ? 'tool-active'
                    : item.isActive
                      ? 'right-tool-active'
                      : ''
                "
                @click="toolbarClick(item)"
              >
                <Icon :icon="item.icon" :size="24" />
                <div class="name"> {{ item.name }} </div>
              </div>
            </template>
            <!-- 位置 -->
            <el-form :model="state.moveForm" v-if="item.switchType === 'move'" class="mt-2">
              <el-form-item label="X">
                <el-input-number
                  v-model="state.moveForm.locationX"
                  :min="0"
                  :max="imgBgObj.width"
                  controls-position="right"
                />
              </el-form-item>
              <el-form-item label="Y">
                <el-input-number
                  v-model="state.moveForm.locationY"
                  :min="0"
                  :max="imgBgObj.height"
                  controls-position="right"
                />
              </el-form-item>
              <div style="text-align: right">
                <el-button
                  size="small"
                  style="width: 64px; height: 30px; background: #00329f"
                  color="#00329F"
                  @click="moveFormSubmit()"
                  >确认</el-button
                >
              </div>
            </el-form>
            <!-- 旋转 -->
            <el-form :model="state.rotationForm" v-if="item.switchType === 'revolve'" class="mt-2">
              <el-form-item label="角度">
                <el-input-number
                  v-model="state.rotationForm.angle"
                  :min="0"
                  :max="259"
                  controls-position="right"
                />
              </el-form-item>
              <div style="text-align: right">
                <el-button
                  size="small"
                  style="width: 64px; height: 30px; background: #00329f"
                  color="#00329F"
                  @click="rotationFormSubmit"
                  >确认</el-button
                >
              </div>
            </el-form>
          </el-popover>
          <!-- 线库 -->
          <el-popover
            placement="bottom"
            trigger="click"
            v-else-if="item.switchType === 'lineLibrary'"
            :popper-style="{ padding: '0px' }"
          >
            <template #reference>
              <div
                class="tool-item"
                :class="
                  toolbarSwitchType === 'lineLibrary' ||
                  toolbarSwitchType === 'createLineLibrary' ||
                  toolbarSwitchType === 'lineLibraryManage'
                    ? 'tool-active'
                    : item.isActive
                      ? 'right-tool-active'
                      : ''
                "
                @click="toolbarClick(item)"
              >
                <Icon :icon="item.icon" :size="24" />
                <div class="name"> {{ item.name }} </div>
              </div>
            </template>
            <div v-if="item.switchType === 'lineLibrary'" class="drop-down-menu">
              <div
                class="drop-down-menu-item"
                :class="toolbarSwitchType === 'createLineLibrary' ? 'right-tool-active' : ''"
                @click="toolbarClick({ switchType: 'createLineLibrary' })"
                >生成线库</div
              >
              <div
                class="drop-down-menu-item"
                :class="toolbarSwitchType === 'lineLibraryManage' ? 'right-tool-active' : ''"
                @click="toolbarClick({ switchType: 'lineLibraryManage' })"
                >线库管理</div
              >
            </div>
          </el-popover>
          <!-- 区域  -->
          <el-popover
            placement="bottom"
            trigger="click"
            v-else-if="item.switchType === 'region'"
            :popper-style="{ padding: '0px' }"
          >
            <template #reference>
              <div
                class="tool-item"
                :class="
                  toolbarSwitchType === 'region' ||
                  toolbarSwitchType === 'createRegion' ||
                  toolbarSwitchType === 'regionManage'
                    ? 'tool-active'
                    : item.isActive
                      ? 'right-tool-active'
                      : ''
                "
                @click="toolbarClick(item)"
              >
                <Icon :icon="item.icon" :size="24" />
                <div class="name"> {{ item.name }} </div>
              </div>
            </template>
            <div v-if="item.switchType === 'region'" class="drop-down-menu">
              <div
                class="drop-down-menu-item"
                :class="toolbarSwitchType === 'createRegion' ? 'right-tool-active' : ''"
                @click="toolbarClick({ switchType: 'createRegion' })"
                >生成物料区域</div
              >
              <div
                class="drop-down-menu-item"
                :class="toolbarSwitchType === 'regionManage' ? 'right-tool-active' : ''"
                @click="toolbarClick({ switchType: 'regionManage' })"
                >物料区域管理</div
              >
            </div>
          </el-popover>
          <!-- 标记 -->
          <el-popover
            placement="bottom"
            trigger="click"
            v-else-if="item.switchType === 'marker'"
            width="220"
            :visible="state.popoverVisible"
          >
            <template #reference>
              <div
                class="tool-item"
                :class="
                  toolbarSwitchType === item.switchType
                    ? 'tool-active'
                    : item.isActive
                      ? 'right-tool-active'
                      : ''
                "
                @click="toolbarClick(item)"
              >
                <Icon :icon="item.icon" :size="24" />
                <div class="name"> {{ item.name }} </div>
              </div>
            </template>
            <!-- 位置 -->
            <el-form :model="state.markForm" class="mt-2" label-width="68">
              <el-form-item label="标记车辆">
                <el-select
                  v-model="state.markForm.macAddress"
                  placeholder="请选择"
                  @change="macAddressChange"
                >
                  <el-option
                    v-for="item in state.mapMarkCarList"
                    :key="item.id"
                    :label="item.robotNo"
                    :value="item.macAddress"
                  />
                </el-select>
              </el-form-item>
              <el-form-item label="标记属性" v-if="state.markForm.markProperty">
                <el-input v-model="state.markForm.markProperty" style="width: 240px" disabled />
              </el-form-item>
              <el-form-item label="原节点" v-if="state.markForm.originalNode">
                <el-input v-model="state.markForm.originalNode" style="width: 240px" disabled />
              </el-form-item>
              <div style="text-align: right">
                <el-button
                  size="small"
                  style="width: 64px; height: 30px; background: #efefef"
                  @click="markFormCancel()"
                  >取消</el-button
                >
                <el-button
                  size="small"
                  style="width: 64px; height: 30px; background: #00329f"
                  color="#00329F"
                  @click="markFormSubmit()"
                  >确认</el-button
                >
              </div>
            </el-form>
          </el-popover>
          <div
            v-else
            class="tool-item"
            :class="
              toolbarSwitchType === item.switchType
                ? 'tool-active'
                : item.isActive
                  ? 'right-tool-active'
                  : ''
            "
            @click="toolbarClick(item)"
          >
            <Icon :icon="item.icon" :size="24" />
            <div class="name"> {{ item.name }} </div>
          </div>
          <!-- 分隔线 -->
          <div
            class="line"
            v-if="
              item.switchType === 'save' ||
              item.switchType === 'delete' ||
              item.switchType === 'grid' ||
              (item.switchType === 'next' &&
                (toolbarSwitchType === 'createLineLibrary' ||
                  toolbarSwitchType === 'createRegion' ||
                  toolbarSwitchType === 'drawRoute' ||
                  toolbarSwitchType === 'generateLine' ||
                  toolbarSwitchType === 'bulkDelete'))
            "
          ></div>
          <el-button
            v-if="
              item.switchType === 'next' &&
              (toolbarSwitchType === 'createLineLibrary' ||
                toolbarSwitchType === 'createRegion' ||
                toolbarSwitchType === 'drawRoute' ||
                toolbarSwitchType === 'generateLine' ||
                toolbarSwitchType === 'bulkDelete')
            "
            type="danger"
            class="selection-area-btn"
            @click="clickDrawSelectionArea"
            >确定</el-button
          >
        </div>
      </div>
      <div class="right-tool-list" v-if="state.isShowToolbar">
        <div
          v-for="item in state.rightToolList"
          :key="item.switchType"
          class="tool-item"
          :class="
            toolbarSwitchType === item.switchType
              ? 'tool-active'
              : item.isActive
                ? 'right-tool-active'
                : ''
          "
          @click="toolbarClick(item)"
        >
          <Icon :icon="item.icon" :size="24" />
          <div class="name"> {{ item.name }} </div>
        </div>
      </div>
    </div>

    <div
      class="map-container"
      ref="mapContainer"
      :style="{ cursor: state.cursorStyle }"
      v-if="imgBgObj.width && imgBgObj.height"
    >
      <!-- <map-scale-tool :stepLength="50" :width="imgBgObj.width" :height="imgBgObj.height"> -->
      <div
        class="map-bg"
        :style="{
          backgroundImage: `url(${imgBgObj.imgUrl})`,
          transform: `scale(${state.imageChangeMultiple})`,
          transformOrigin: '0 0',
          width: `${imgBgObj.width}px`,
          height: `${imgBgObj.height}px`
        }"
        @mousedown="startDrawSelection"
        @mousemove="updateDrawSelection"
        @mouseup="endDrawSelection"
      >
        <div
          ref="mapBackgroundRef"
          class="map-box-inner"
          @click="mapClick"
          :class="state.isShowGrid ? 'grid-show' : ''"
          :style="{
            width: imgBgObj.width + 'px',
            height: imgBgObj.height + 'px'
          }"
          v-if="interfaceRefreshed"
        >
          <VueDragResizeRotate
            v-for="(item, index) in state.allMapPointInfo"
            :key="index + Number(item.locationX)"
            :parent="true"
            :x="Number(item.locationX) - Number(item.locationWidePx) / 2"
            :y="Number(item.locationY) - Number(item.locationDeepPx) / 2"
            :w="Number(item.locationWidePx)"
            :h="Number(item.locationDeepPx)"
            :r="item.angle"
            @rotatestop="(degree) => rotateEnd(degree, item, index)"
            @dragstop="(x, y) => dragEnd(x, y, item, index)"
            @resizestop="(x, y, width, height) => resizeEnd(x, y, width, height, item, index)"
            @activated="() => activatedHandle(item, index)"
            @deactivated="deactivatedHandle"
            :draggable="!state.prohibitedOperation && item.draggable"
            :resizable="!state.prohibitedOperation && item.resizable"
            :rotatable="!state.prohibitedOperation && item.rotatable"
            :lock-aspect-ratio="item.lockAspectRatio"
            :scaleRatio="state.imageChangeMultiple"
            style="border: none; z-index: 999"
          >
            <!-- 节点合集 -->
            <div
              @mousedown="startFromPoint(index, $event)"
              :style="{ width: item.locationWidePx + 'px', height: item.locationDeepPx + 'px' }"
            >
              <!-- 1 路径点 -->
              <el-tooltip effect="dark" placement="top" trigger="click">
                <template #content>
                  <div v-if="item.type === 1">
                    <div>序号：{{ item.sortNum || '节点未保存' }}</div>
                  </div>
                  <div v-else-if="item.type === 2">
                    <div>序号：{{ item.sortNum || '节点未保存' }}</div>
                    <div class="item-tooltip-name" v-if="item.laneId && item.laneName">
                      所属线库：{{ item.laneName }}
                    </div>
                    <div class="item-tooltip-name" v-if="item.areaId && item.areaName">
                      所属区域：{{ item.areaName }}
                    </div>
                  </div>
                  <div v-else-if="item.type === 3">
                    <div>序号：{{ item.sortNum || '节点未保存' }}</div>
                    <div class="item-tooltip-name" v-if="item.deviceType">
                      设备类型：{{ getDeviceTypeName(item.deviceType) }}
                    </div>
                    <div class="item-tooltip-name" v-if="item.deviceNo">
                      设备编号：{{ item.deviceNo }}
                    </div>
                  </div>
                  <div v-else>
                    <div>序号：{{ item.sortNum || '节点未保存' }}</div>
                    <div class="item-tooltip-name">
                      节点类型：{{
                        item.type == 4
                          ? '停车点'
                          : item.type == 5
                            ? '区域变更点'
                            : item.type == 6
                              ? '等待点'
                              : ''
                      }}
                    </div>
                  </div>
                </template>
                <div>
                  <div
                    v-if="
                      item.type === 1 &&
                      item.layerSelectionShow &&
                      state.isShowSortNum &&
                      item.sortNum
                    "
                    class="sort-num"
                    :style="getSortNumStyle(item, index)"
                  >
                    {{ item.sortNum }}
                  </div>
                  <div
                    v-if="
                      item.type !== 1 &&
                      item.layerSelectionShow &&
                      state.isShowSortNum &&
                      item.sortNum
                    "
                    class="sort-num-location"
                    :style="getSortNumLocationStyle(item, index)"
                  >
                    {{ item.sortNum }}
                  </div>
                  <div
                    class="sort-num-location"
                    :style="getLocationNumberStyle(item, index)"
                    v-if="
                      toolbarSwitchType === 'createLineLibrary' &&
                      item.type === 2 &&
                      item.locationNumber
                    "
                  >
                    {{ item.locationNumber }}
                  </div>
                  <div
                    v-if="item.type === 1 && item.layerSelectionShow"
                    :style="{
                      width: item.locationWidePx + 'px',
                      height: item.locationDeepPx + 'px',
                      backgroundColor: state.currentItemIndex === index ? '#5ecc62' : '#000',
                      borderRadius: '50%',
                      zIndex: 999
                    }"
                  >
                  </div>
                  <!-- 2 库位点 -->
                  <img
                    v-if="item.type === 2 && item.layerSelectionShow"
                    src="https://api.znkjfw.com/admin-api/infra/file/4/get/库位库存_png_179_1744098544821.png"
                    alt=""
                    :style="binLocationStyle(item, index)"
                  />
                  <!-- 3 设备点 -->
                  <img
                    v-if="item.type === 3 && item.layerSelectionShow"
                    :src="
                      item.mapImageUrl ||
                      'https://api.znkjfw.com/admin-api/infra/file/4/get/设备 (4)_png_179_1744102025024.png'
                    "
                    alt=""
                    style="background: #fff"
                    :style="nodeStyle(item, index)"
                  />
                  <!-- 4 停车点 -->
                  <img
                    v-if="item.type === 4 && item.layerSelectionShow"
                    src="https://api.znkjfw.com/admin-api/infra/file/4/get/停车位_png_179_1744098982069.png"
                    alt=""
                    style="background: #fff"
                    :style="nodeStyle(item, index)"
                  />
                  <!-- 5 区域变更点 -->
                  <img
                    v-if="item.type === 5 && item.layerSelectionShow"
                    src="https://api.znkjfw.com/admin-api/infra/file/4/get/区域变更 (1)_png_179_1744100605191.png"
                    alt=""
                    style="background: #fff"
                    :style="nodeStyle(item, index)"
                  />
                  <!-- 6 等待点 -->
                  <img
                    v-if="item.type === 6 && item.layerSelectionShow"
                    src="https://api.znkjfw.com/admin-api/infra/file/4/get/等待_png_179_1744102070670.png"
                    alt=""
                    style="background: #fff"
                    :style="nodeStyle(item, index)"
                  />
                </div>
              </el-tooltip>
            </div>
            <div
              class="node-text"
              v-if="item.type === 7 && item.layerSelectionShow"
              :style="{
                position: 'absolute',
                color: item.fontColor,
                fontSize: item.fontSize + 'px',
                fontFamily: item.fontFamily,
                border: state.currentItemIndex === index ? '1px dashed #000' : 'none'
              }"
            >
              {{ item.text }}
            </div>
          </VueDragResizeRotate>

          <div v-if="imgBgObj.width && imgBgObj.height">
            <svg
              :width="imgBgObj.width"
              :height="imgBgObj.height"
              style="position: absolute; top: 0; left: 0; z-index: 9"
              id="svgId"
            >
              <!-- 实时绘制当前直线 -->
              <line
                v-if="state.isDrawing && toolbarSwitchType === 'clickDrawRoute'"
                :x1="Number(state.startDrawPoint.locationX)"
                :y1="Number(state.startDrawPoint.locationY)"
                :x2="Number(state.currentDrawX)"
                :y2="Number(state.currentDrawY)"
                stroke="#2d72d9"
                stroke-width="5"
              />
              <template v-if="state.mapRouteList.length > 0">
                <template v-for="(curve, index) in state.mapRouteList" :key="index">
                  <!-- 直线 -->
                  <template v-if="curve.method === 0">
                    <line
                      :x1="Number(curve.startPointX)"
                      :y1="Number(curve.startPointY)"
                      :x2="Number(curve.endPointX)"
                      :y2="Number(curve.endPointY)"
                      :stroke="curve.isSelected ? '#f48924' : '#2d72d9'"
                      stroke-width="5"
                      @click="handleChooseRoute(curve, index)"
                    />
                    <text
                      style="user-select: none"
                      :x="(Number(curve.startPointX) + Number(curve.endPointX)) / 2"
                      :y="(Number(curve.startPointY) + Number(curve.endPointY) - 18) / 2"
                      font-size="11"
                      text-anchor="middle"
                      fill="black"
                      v-if="curve.isSelected"
                      @click="handleChooseRoute(curve, index)"
                    >
                      {{ calculateRouteLength(curve, 'line') }}米
                    </text>
                  </template>

                  <template v-else>
                    <path
                      id="curvePath"
                      :d="getCurvePath(curve)"
                      :stroke="curve.isSelected ? '#f48924' : '#2d72d9'"
                      stroke-width="5"
                      fill="none"
                      @click="handleChooseRoute(curve, index)"
                    />
                    <text
                      style="user-select: none"
                      :x="computedCurveTextX(curve)"
                      :y="computedCurveTextY(curve)"
                      font-size="11"
                      text-anchor="middle"
                      fill="black"
                      v-if="curve.isSelected"
                      @click="handleChooseRoute(curve, index)"
                    >
                      {{ calculateRouteLength(curve, 'curve') }}米
                    </text>

                    <!-- 第一条控制线 -->
                    <line
                      v-if="state.currentDragTarget.index == index"
                      :x1="Number(curve.startPointX)"
                      :y1="Number(curve.startPointY)"
                      :x2="curve.beginControlX"
                      :y2="curve.beginControlY"
                      :stroke="curve.isSelected ? '#f48924' : '#2d72d9'"
                      stroke-dasharray="4"
                      stroke-width="2"
                    />
                    <!-- 第二条控制线 -->
                    <line
                      v-if="state.currentDragTarget.index == index"
                      :x1="Number(curve.endPointX)"
                      :y1="Number(curve.endPointY)"
                      :x2="curve.endControlX"
                      :y2="curve.endControlY"
                      :stroke="curve.isSelected ? '#f48924' : '#2d72d9'"
                      stroke-dasharray="4"
                      stroke-width="2"
                    />
                    <circle
                      v-if="state.currentDragTarget.index == index"
                      id="startCircle"
                      :cx="curve.beginControlX"
                      :cy="curve.beginControlY"
                      r="5"
                      :fill="curve.isSelected ? '#f48924' : '#2d72d9'"
                      @mousedown="startDrag(curve, index, 'start')"
                    />
                    <circle
                      v-if="state.currentDragTarget.index == index"
                      id="endCircle"
                      :cx="curve.endControlX"
                      :cy="curve.endControlY"
                      r="5"
                      :fill="curve.isSelected ? '#f48924' : '#2d72d9'"
                      @mousedown="startDrag(curve, index, 'end')"
                    />
                  </template>
                </template>
              </template>
            </svg>
          </div>
        </div>

        <!-- 框选区域 -->
        <div
          v-for="(box, index) in state.allDrawSelectionAreaBox"
          :key="index"
          :style="{
            position: 'absolute',
            left: `${box.x}px`,
            top: `${box.y}px`,
            width: `${box.width}px`,
            height: `${box.height}px`,
            border: '2px dashed #007bff',
            backgroundColor: 'rgba(0, 123, 255, 0.1)',
            zIndex: 999
          }"
        ></div>
        <!-- 当前框选区域 -->
        <div
          v-if="state.drawSelectionAreaShow"
          :style="{
            position: 'absolute',
            left: `${state.drawSelectionAreaBox.x}px`,
            top: `${state.drawSelectionAreaBox.y}px`,
            width: `${state.drawSelectionAreaBox.width}px`,
            height: `${state.drawSelectionAreaBox.height}px`,
            border: '2px dashed #007bff',
            backgroundColor: 'rgba(0, 123, 255, 0.1)',
            zIndex: 9999
          }"
        ></div>

        <!-- 测距 绘制点和连线 -->
        <template v-if="state.measureDistancesPoints.length > 0">
          <!-- 测距的线 -->
          <div v-if="state.measureDistancesPoints.length === 2" :style="rangingLineStyle"></div>
          <!-- 显示距离信息 -->
          <div v-if="state.measureDistancesNum !== null" :style="rangingTextStyle">
            {{ state.measureDistancesNum.toFixed(2) }}米
          </div>
          <!-- 测距的点 -->
          <div
            v-for="(point, index) in state.measureDistancesPoints"
            :key="index"
            :style="getRangingPointStyle(point)"
          ></div>
        </template>

        <!-- 文字输入区域 -->
        <input
          v-if="state.showInputBox"
          ref="inputBoxRef"
          v-model="state.inputBoxValue"
          @keyup.enter="handleInputEnd"
          @blur="handleInputEnd"
          :style="{
            fontSize: state.inputBoxStyle.fontSize + 'px',
            fontFamily: state.inputBoxStyle.fontFamily,
            color: state.inputBoxStyle.fontColor,
            left: state.inputBoxStyle.locationX + 'px',
            top: state.inputBoxStyle.locationY + 'px'
          }"
          :maxlength="30"
          class="input-box-class"
        />
      </div>
      <!-- </map-scale-tool> -->
    </div>

    <div class="actual-location" v-if="state.actualLocation.x && state.actualLocation.y">
      <div>X：{{ state.actualLocation.x }}</div>
      <div>Y：{{ state.actualLocation.y }}</div>
    </div>

    <!-- 节点编辑 -->
    <editNodeProperties
      v-if="imgBgObj.positionMapId"
      ref="editNodePropertiesRef"
      :positionMapId="imgBgObj.positionMapId"
      :imgBgObj="imgBgObj"
      @submitNodeSuccess="submitNodeSuccess"
      @addEventListener="addEventListener"
    />
    <!-- 文字输入弹窗 -->
    <textFormToolDialog
      ref="textFormToolDialogRef"
      v-if="state.textFormToolShow"
      :inputBoxStyle="state.inputBoxStyle"
      @textFormSuccess="textFormSuccess"
    />
    <!-- 图层选择 -->
    <layerSelectionToolDialog
      v-if="state.isShowLayer"
      ref="layerSelectionToolDialogRef"
      @layerSelectionSuccess="layerSelectionSuccess"
    />
    <!-- 设备弹窗选择 -->
    <equipmentToolDialog
      ref="equipmentToolDialogRef"
      :positionMapId="imgBgObj.positionMapId"
      @addEventListener="addEventListener"
    />
    <!-- 区域选择 -->
    <itemAreaSettingDialog
      ref="itemAreaSettingDialogRef"
      :positionMapId="imgBgObj.positionMapId"
      @addEventListener="addEventListener"
      @itemAreaSettingSubmitSuccess="itemAreaSettingSubmitSuccess"
    />
    <!-- 线库设置 -->
    <lineLibrarySettingDialog
      ref="lineLibrarySettingDialogRef"
      :positionMapId="imgBgObj.positionMapId"
      @addEventListener="addEventListener"
      @submitLineLibraryFormSuccess="submitLineLibraryFormSuccess"
    />
    <!-- 编辑地图路线 -->
    <editMapRouteDialog
      v-if="imgBgObj.positionMapId"
      ref="editMapRouteDialogRef"
      @editMapRouteDialogSubmit="editMapRouteDialogSubmit"
      @addEventListener="addEventListener"
      :imgBgObj="imgBgObj"
    />
    <!-- 线库管理 -->
    <lineLibraryManagementDialog
      ref="lineLibraryManagementDialogRef"
      :positionMapId="imgBgObj.positionMapId"
      @addEventListener="addEventListener"
      @lineLibraryManagementDelete="lineLibraryManagementDelete"
      @lineLibraryManagementEdit="lineLibraryManagementEdit"
    />
    <!-- 区域管理 -->
    <itemAreaManagementDialog
      ref="itemAreaManagementDialogRef"
      :positionMapId="imgBgObj.positionMapId"
      @addEventListener="addEventListener"
      @itemAreaManagementDelete="itemAreaManagementDelete"
      @itemAreaManagementEdit="itemAreaManagementEdit"
    />
    <!-- 生成直线 选择开始点和结束点 -->
    <GenerateStraightLinesDialog
      ref="GenerateStraightLinesDialogRef"
      @GenerateStraightLinesSubmit="GenerateStraightLinesSubmit"
    />
  </div>
</template>

<script setup>
import JSONBigInt from 'json-bigint'
import { ElLoading } from 'element-plus'
import { ref, defineComponent, reactive, nextTick, onMounted } from 'vue'
import editMapRouteDialog from './components-tool/editMapRouteDialog.vue'
import editNodeProperties from './components-tool/editNodeProperties.vue'
import textFormToolDialog from './components-tool/textFormToolDialog.vue'
import equipmentToolDialog from './components-tool/equipmentToolDialog.vue'
import itemAreaSettingDialog from './components-tool/itemAreaSettingDialog.vue'
import lineLibrarySettingDialog from './components-tool/lineLibrarySettingDialog.vue'
import layerSelectionToolDialog from './components-tool/layerSelectionToolDialog.vue'
import itemAreaManagementDialog from './components-tool/itemAreaManagementDialog.vue'
import lineLibraryManagementDialog from './components-tool/lineLibraryManagementDialog.vue'
import GenerateStraightLinesDialog from './components-tool/GenerateStraightLinesDialog.vue'
import mapScaleTool from './components-tool/map-scale-tool.vue'

import * as MapApi from '@/api/map/map'
import cursorCollection from './cursorCollection'
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'

defineOptions({ name: 'editMapPageRealTimeMap' })

const GenerateStraightLinesDialogRef = ref() //生成直线的
const lineLibraryManagementDialogRef = ref() //线库管理
const itemAreaManagementDialogRef = ref() //区域管理
const lineLibrarySettingDialogRef = ref() //线库设置
const itemAreaSettingDialogRef = ref() //物料区域设置
const equipmentToolDialogRef = ref() //设备弹窗
const textFormToolDialogRef = ref() //文字输入弹窗
const editMapRouteDialogRef = ref() //编辑地图路线的弹窗
const mapBackgroundRef = ref()
const inputBoxRef = ref() //文字输入框

const message = useMessage() // 消息弹窗

//其他节点的样式
const nodeStyle = (item, index) => {
  return {
    verticalAlign: 'top',
    width: item.locationWidePx + 'px',
    height: item.locationDeepPx + 'px',
    border: state.currentItemIndex === index ? '1px dashed #000' : 'none',
    borderRadius: '3px'
  }
}
//sortNum路径点的样式
const getSortNumStyle = (item, index) => {
  let leftNum = 0
  if (item.sortNum.toString().length === 1) {
    leftNum = 3
  } else if (item.sortNum.toString().length === 2) {
    leftNum = 7
  } else if (item.sortNum.toString().length === 3) {
    leftNum = 10
  } else if (item.sortNum.toString().length === 4) {
    leftNum = 14
  } else if (item.sortNum.toString().length === 5) {
    leftNum = 18
  } else if (item.sortNum.toString().length === 6) {
    leftNum = 21
  } else if (item.sortNum.toString().length === 7) {
    leftNum = 25
  } else if (item.sortNum.toString().length === 8) {
    leftNum = 28
  } else if (item.sortNum.toString().length === 9) {
    leftNum = 31
  }
  return {
    left: Number(item.locationWidePx) / 2 - leftNum + 'px',
    top: 6 + 'px'
  }
}
//sortNum非路径点的样式
const getSortNumLocationStyle = (item, index) => {
  let leftNum = 0
  if (item.sortNum.toString().length === 1) {
    leftNum = 3
  } else if (item.sortNum.toString().length === 2) {
    leftNum = 7
  } else if (item.sortNum.toString().length === 3) {
    leftNum = 10
  } else if (item.sortNum.toString().length === 4) {
    leftNum = 14
  } else if (item.sortNum.toString().length === 5) {
    leftNum = 18
  } else if (item.sortNum.toString().length === 6) {
    leftNum = 21
  } else if (item.sortNum.toString().length === 7) {
    leftNum = 25
  } else if (item.sortNum.toString().length === 8) {
    leftNum = 28
  } else if (item.sortNum.toString().length === 9) {
    leftNum = 31
  }
  return {
    left: Number(item.locationWidePx) / 2 - leftNum + 'px',
    top: Number(item.locationDeepPx) / 2 - 2 + 'px'
  }
}
//排序的样式
const getLocationNumberStyle = (item, index) => {
  let leftNum = 0
  if (item.locationNumber.toString().length === 1) {
    leftNum = 3
  } else if (item.locationNumber.toString().length === 2) {
    leftNum = 7
  } else if (item.locationNumber.toString().length === 3) {
    leftNum = 10
  } else if (item.locationNumber.toString().length === 4) {
    leftNum = 14
  } else if (item.locationNumber.toString().length === 5) {
    leftNum = 18
  } else if (item.locationNumber.toString().length === 6) {
    leftNum = 21
  } else if (item.locationNumber.toString().length === 7) {
    leftNum = 25
  } else if (item.locationNumber.toString().length === 8) {
    leftNum = 28
  } else if (item.locationNumber.toString().length === 9) {
    leftNum = 31
  }
  return {
    left: Number(item.locationWidePx) / 2 - leftNum + 'px',
    top: Number(item.locationDeepPx) / 2 - 2 + 'px'
  }
}

//库位的样式
const binLocationStyle = (item, index) => {
  let laneId
  let areaId
  if (state.currentItemIndex !== -1) {
    laneId = state.allMapPointInfo[state.currentItemIndex].laneId
    areaId = state.allMapPointInfo[state.currentItemIndex].areaId
  }
  return {
    verticalAlign: 'top',
    width: item.locationWidePx + 'px',
    height: item.locationDeepPx + 'px',
    border:
      state.currentItemIndex === index
        ? '1px dashed #000'
        : state.noLocationNumberList.includes(index)
          ? '1px dashed red'
          : (laneId && item.laneId === laneId) || (areaId && item.areaId === areaId)
            ? '1px dashed #ff6a00'
            : 'none'
  }
}

// 缩放停止
const interfaceRefreshed = ref(true)
const resizeEnd = (locationX, locationY, w, h, item, index) => {
  interfaceRefreshed.value = false
  nextTick(() => {
    let x = Number(locationX) + Number(item.locationWidePx) / 2
    let y = Number(locationY) + Number(item.locationDeepPx) / 2
    let width = Number(w) * imgBgObj.resolution * 100 //实际的宽高cm
    let height = Number(h) * imgBgObj.resolution * 100

    let actualPoint = disposeEventPoint(x, y)

    state.allMapPointInfo[index].locationX = x
    state.allMapPointInfo[index].locationY = y
    state.allMapPointInfo[index].locationWide = width
    state.allMapPointInfo[index].locationDeep = height
    state.allMapPointInfo[index].locationWidePx = w
    state.allMapPointInfo[index].locationDeepPx = h
    state.allMapPointInfo[index].actualLocationX = actualPoint.actualLocationX
    state.allMapPointInfo[index].actualLocationY = actualPoint.actualLocationY
    //更改路线里的
    state.mapRouteList.forEach((route) => {
      if (item.id === route.startingPointId) {
        route.startPointX = x
        route.startPointY = y
        route.beginHigh = Number(item.locationDeepPx)
        route.beginWidth = Number(item.locationWidePx)
        route.actualStartPointX = actualPoint.actualLocationX
        route.actualStartPointY = actualPoint.actualLocationY
      }
      if (item.id === route.endPointId) {
        route.endPointX = x
        route.endPointY = y
        route.endHigh = Number(item.locationDeepPx)
        route.endWidth = Number(item.locationWidePx)
        route.actualEndPointX = actualPoint.actualLocationX
        route.actualEndPointY = actualPoint.actualLocationY
      }
    })
    addEditHistory()
  })
}

// 拖拽停止
const dragEnd = (locationX, locationY, item, index) => {
  let x = Number(locationX) + Number(item.locationWidePx) / 2
  let y = Number(locationY) + Number(item.locationDeepPx) / 2

  if (x === item.locationX && y === item.locationY) return
  let actualPoint = disposeEventPoint(x, y)
  state.allMapPointInfo[index].locationX = x
  state.allMapPointInfo[index].locationY = y
  state.allMapPointInfo[index].actualLocationX = actualPoint.actualLocationX
  state.allMapPointInfo[index].actualLocationY = actualPoint.actualLocationY
  //更改路线里的
  state.mapRouteList.forEach((route) => {
    if (item.id === route.startingPointId) {
      route.startPointX = x
      route.startPointY = y
      route.beginHigh = Number(item.locationDeepPx)
      route.beginWidth = Number(item.locationWidePx)
      route.actualStartPointX = actualPoint.actualLocationX
      route.actualStartPointY = actualPoint.actualLocationY
    }
    if (item.id === route.endPointId) {
      route.endPointX = x
      route.endPointY = y
      route.endHigh = Number(item.locationDeepPx)
      route.endWidth = Number(item.locationWidePx)
      route.actualEndPointX = actualPoint.actualLocationX
      route.actualEndPointY = actualPoint.actualLocationY
    }
  })
  addEditHistory()
}
// 旋转
const rotateEnd = (angle, item, index) => {
  state.allMapPointInfo[index].angle = angle
  addEditHistory()
}

//节点选中
const editNodePropertiesRef = ref()
const activatedHandle = (item, index) => {
  state.currentItemIndex = index

  //让路线不选中
  state.selectedCurve = ''
  if (state.mapRouteList.length > 0 && state.currentDragTarget.index !== null) {
    state.mapRouteList[state.currentDragTarget.index].isSelected = false
    state.currentDragTarget = { index: null, type: null }
  }

  //显示出可走路线
  state.isCanTakeRoutes = state.mapRouteList.forEach((route) => {
    if (
      route.startingPointId === item.id ||
      (route.direction === 2 && route.endPointId === item.id)
    ) {
      route.isSelected = true
    } else {
      route.isSelected = false
    }
  })

  //节点编辑
  if (toolbarSwitchType.value === 'editNode' && item.type !== 7) {
    let list = state.allMapPointInfo.filter((item) => item.type === 3)
    removeEventListener() //移除监听
    editNodePropertiesRef.value.open(JSON.parse(JSON.stringify(item)), list)
  }
}
//非选中
const deactivatedHandle = () => {}

//添加历史记录
const addEditHistory = () => {
  //要判断是不是在最新的记录上修改 如果不是 要把currentIndex之后的记录都删掉 保持当前修改是最新的
  if (state.currentIndex < state.allHistoryList.length - 1) {
    state.allHistoryList.splice(state.currentIndex + 1)
  }
  state.allHistoryList.push({
    allMapPointInfo: JSON.parse(JSON.stringify(state.allMapPointInfo)),
    mapRouteList: JSON.parse(JSON.stringify(state.mapRouteList))
  })
  state.currentIndex = state.allHistoryList.length - 1
  interfaceRefreshed.value = true
}

//上一步
const backPreviousStep = () => {
  if (state.currentIndex > 0) {
    state.currentIndex--
    state.allMapPointInfo.splice(
      0,
      state.allMapPointInfo.length,
      ...JSON.parse(JSON.stringify(state.allHistoryList[state.currentIndex]?.allMapPointInfo))
    )
    state.mapRouteList.splice(
      0,
      state.mapRouteList.length,
      ...JSON.parse(JSON.stringify(state.allHistoryList[state.currentIndex]?.mapRouteList))
    )
  } else {
    message.warning('没了老铁')
  }
}
//下一步
const backNextStep = () => {
  if (state.currentIndex < state.allHistoryList.length - 1) {
    state.currentIndex++
    state.allMapPointInfo.splice(
      0,
      state.allMapPointInfo.length,
      ...JSON.parse(JSON.stringify(state.allHistoryList[state.currentIndex]?.allMapPointInfo))
    )
    state.mapRouteList.splice(
      0,
      state.mapRouteList.length,
      ...JSON.parse(JSON.stringify(state.allHistoryList[state.currentIndex]?.mapRouteList))
    )
  } else {
    message.warning('没了老铁')
  }
}

//地图点击
const mapClick = (e) => {
  const x = disposeEventPoints(e).x
  const y = disposeEventPoints(e).y
  const actualLocationX = disposeEventPoints(e).actualLocationX
  const actualLocationY = disposeEventPoints(e).actualLocationY

  state.actualLocation.x = actualLocationX
  state.actualLocation.y = actualLocationY

  //新增节点
  if (toolbarSwitchType.value === 'drawNodes') {
    state.allMapPointInfo.push({
      positionMapId: imgBgObj.positionMapId, //地图的id
      layerSelectionShow: true,
      locationX: x,
      locationY: y,
      actualLocationX: actualLocationX,
      actualLocationY: actualLocationY,
      locationDeep: 40,
      locationWide: 40,
      locationDeepPx: 8,
      locationWidePx: 8,
      angle: 0,
      draggable: true,
      resizable: true,
      rotatable: false,
      lockAspectRatio: false, //横纵比
      mapImageUrl: '',
      locationYaw: 0, //弧度
      type: 1, //默认类型1 路径节点
      dataList: [], //存库位的
      dataObj: {} //存 设备点 停车点 文字
    })
    addEditHistory()
  }
  //文字输入
  if (toolbarSwitchType.value === 'text') {
    state.showInputBox = true
    state.inputBoxStyle.locationX = x
    state.inputBoxStyle.locationY = y
    state.inputBoxStyle.actualLocationX = actualLocationX
    state.inputBoxStyle.actualLocationY = actualLocationY

    // 聚焦输入框
    setTimeout(() => {
      inputBoxRef.value.focus()
    }, 0)
  }
  //测距
  if (toolbarSwitchType.value === 'ranging') {
    measureDistancesClick(e)
  }
}
//输入文字样式改变
const textFormSuccess = (form) => {
  state.inputBoxStyle.fontSize = `${form.fontSize}`
  state.inputBoxStyle.fontFamily = `${form.fontFamily}`
  state.inputBoxStyle.fontColor = `${form.fontColor}`
}
//输入结束
const handleInputEnd = () => {
  if (state.inputBoxValue) {
    state.showInputBox = false
    state.allMapPointInfo.push({
      type: 7, //类型  7文字
      positionMapId: imgBgObj.positionMapId, //地图的id
      locationX: state.inputBoxStyle.locationX, //x
      locationY: state.inputBoxStyle.locationY, //y
      actualLocationX: state.inputBoxStyle.actualLocationX,
      actualLocationY: state.inputBoxStyle.actualLocationY,
      locationDeep: null, //h
      locationWide: null, //w
      angle: 0, //旋转角度
      draggable: true, //是否可以拖动
      resizable: false, //是否可以调整大小
      rotatable: true, //是否可以旋转
      lockAspectRatio: true, //是否锁定比例
      mapImageUrl: '', //图片
      text: state.inputBoxValue, //文字内容
      fontColor: state.inputBoxStyle.fontColor, //文字颜色
      fontFamily: state.inputBoxStyle.fontFamily, //字体类型
      fontSize: state.inputBoxStyle.fontSize,
      dataObj: {}, //存 设备点 停车点 文字
      layerSelectionShow: true,
      locationDeep: 20,
      locationWide: 20,
      locationDeepPx: 4,
      locationWidePx: 4
    })
    addEditHistory()
    state.inputBoxValue = ''
  }
}
//编辑节点成功
const submitNodeSuccess = (form) => {
  form.locationDeepPx = Number(form.locationDeep) / 100 / imgBgObj.resolution
  form.locationWidePx = Number(form.locationWide) / 100 / imgBgObj.resolution
  state.allMapPointInfo[state.currentItemIndex] = form

  //节点位置改变 通知路径里面的节点也改变
  state.mapRouteList.forEach((item) => {
    if (form.id === item.startingPointId) {
      item.startPointX = form.locationX
      item.startPointY = form.locationY
      item.beginHigh = Number(form.locationDeepPx)
      item.beginWidth = Number(form.locationWidePx)
      item.actualStartPointX = disposeEventPoint(form.locationX, form.locationY).actualLocationX
      item.actualStartPointY = disposeEventPoint(form.locationX, form.locationY).actualLocationY
    }
    if (form.id === item.endPointId) {
      item.endPointX = form.locationX
      item.endPointY = form.locationY
      item.endHigh = Number(form.locationDeepPx)
      item.endWidth = Number(form.locationWidePx)
      item.actualEndPointX = disposeEventPoint(form.locationX, form.locationY).actualLocationX
      item.actualEndPointY = disposeEventPoint(form.locationX, form.locationY).actualLocationY
    }
  })
  addEditHistory()

  //存在库位未填写排序号的问题
  state.noLocationNumberList = state.allMapPointInfo.reduce((invalidIndexes, item, index) => {
    if (item.type === 2 && !item.locationNumber) {
      invalidIndexes.push(index) // 如果不满足条件，记录索引
    }
    return invalidIndexes
  }, [])
}

//工具栏点击
const toolbarSwitchType = ref('')
const state = reactive({
  topToolList: [
    // {
    //   switchType: 'open',
    //   name: '打开',
    //   icon: 'ep:folder-add',
    //   isActive: false
    // },
    {
      switchType: 'save',
      name: '保存',
      icon: 'ep:folder-checked',
      isActive: false
    },
    // {
    //   switchType: 'saveAs',
    //   name: '另存为',
    //   icon: 'ep:folder-opened',
    //   isActive: false
    // },
    {
      switchType: 'choose',
      name: '选择',
      icon: 'ep:position',
      isActive: false
    },
    {
      switchType: 'move',
      name: '移动',
      icon: 'ep:rank',
      isActive: false
    },
    {
      switchType: 'revolve',
      name: '旋转',
      icon: 'ep:refresh-right',
      isActive: false
    },
    {
      switchType: 'copy',
      name: '复制',
      icon: 'ep:document',
      isActive: false
    },
    {
      switchType: 'paste',
      name: '粘贴',
      icon: 'ep:copy-document',
      isActive: false
    },
    {
      switchType: 'delete',
      name: '删除',
      icon: 'ep:delete',
      isActive: false
    },
    {
      switchType: 'tools',
      name: '工具',
      icon: 'ep:briefcase',
      isActive: false
    },
    {
      switchType: 'lineLibrary',
      name: '线库',
      icon: 'ep:message-box',
      isActive: false
    },
    {
      switchType: 'region',
      name: '区域',
      icon: 'ep:full-screen',
      isActive: false
    },
    {
      switchType: 'text',
      name: '文字',
      icon: 'ep:edit-pen',
      isActive: false
    },
    {
      switchType: 'equipment',
      name: '设备',
      icon: 'ep:video-camera-filled',
      isActive: false
    },
    {
      switchType: 'ranging',
      name: '测距',
      icon: 'ep:folder-add',
      isActive: false
    },
    {
      switchType: 'layer',
      name: '图层',
      icon: 'ep:copy-document',
      isActive: false
    },
    {
      switchType: 'marker',
      name: '标记',
      icon: 'ep:map-location',
      isActive: false
    },
    {
      switchType: 'grid',
      name: '网格',
      icon: 'ep:grid',
      isActive: false
    },
    {
      switchType: 'larger',
      name: '放大',
      icon: 'ep:zoom-in',
      isActive: false
    },
    {
      switchType: 'smaller',
      name: '缩小',
      icon: 'ep:zoom-out',
      isActive: false
    },
    {
      switchType: 'withdraw',
      name: '撤回',
      icon: 'ep:top-left',
      isActive: false
    },
    {
      switchType: 'next',
      name: '重做',
      icon: 'ep:top-right',
      isActive: false
    }
  ],
  rightToolList: [
    {
      switchType: 'drawNodes',
      name: '新增节点',
      icon: 'ep:circle-plus-filled',
      isActive: false
    },
    {
      switchType: 'editNode',
      name: '编辑节点',
      icon: 'ep:circle-plus-filled',
      isActive: false
    },
    {
      switchType: 'clickDrawRoute',
      name: '新增路线',
      icon: 'ep:semi-select',
      isActive: false
    },
    // {
    //   switchType: 'drawRoute',
    //   name: '框选绘制',
    //   icon: 'ep:semi-select',
    //   isActive: false
    // },
    {
      switchType: 'editRoute',
      name: '编辑路线',
      icon: 'ep:semi-select',
      isActive: false
    },
    {
      switchType: 'generateLine',
      name: '生成直线',
      icon: 'ep:finished',
      isActive: false
    },
    {
      switchType: 'bulkDelete',
      name: '批量删除',
      icon: 'ep:delete',
      isActive: false
    },
    {
      switchType: 'showSortNum',
      name: '节点序号',
      icon: 'ep:chat-dot-square',
      isActive: false
    }
  ],
  isShowToolbar: false, //工具栏展示隐藏
  isShowGrid: false, //网格展示隐藏
  moveForm: {
    locationX: 0,
    locationY: 0
  }, //移动的表单
  rotationForm: {
    angle: 0
  }, //旋转的表单
  copyMapItem: '', //复制的值
  cursorStyle: 'auto',
  drawSelectionAreaShow: false, //绘制框选区域
  allDrawSelectionAreaBox: [], // 所有框选区域
  drawSelectionAreaBox: { x: 0, y: 0, width: 0, height: 0 }, //绘制区域的位置，长宽
  drawSelectionStartPoint: { x: 0, y: 0 }, //开始绘制的点位
  drawSelectionPointList: [], //绘制选中的list
  textFormToolShow: false, //文字表单显示隐藏
  showInputBox: false, //输入框显示隐藏
  inputBoxStyle: {
    fontFamily: 'SimSun',
    fontSize: '14',
    fontColor: '#000000',
    locationX: 0,
    locationY: 0,
    actualLocationX: 0,
    actualLocationY: 0
  }, //输入框的样式
  inputBoxValue: '', //输入的值
  isShowLayer: false, //图层显示
  measureDistancesPoints: [], // 存储点击的点位
  measureDistancesNum: 0, // 存储两点之间的距离
  imageChangeMultiple: 1, //图片放大缩小的倍数
  prohibitedOperation: false, //禁止操作 在框选测距等操作时，禁止所有拖动等操作
  currentDragTarget: {
    index: null,
    type: null
  }, //当前拖拽的目标（起点、终点、控制点）
  selectedCurve: '', // 当前选中的曲线
  startDrawPointIndex: -1, // 起始点的索引
  startDrawPoint: null, //新增路线开始的点
  isDrawing: false, //正在绘制
  currentDrawX: 0, //正在绘制的x轴坐标
  currentDrawY: 0, //正在绘制的y轴坐标
  allHistoryList: [], //所有的历史记录 [{allMapPointInfo:[],mapRouteList:[]}]
  allMapPointInfo: [], //当前页面上的所有节点的列表
  mapRouteList: [], //当前页面上所有路线的列表
  currentIndex: 0, //当前处在哪条历史记录
  currentItemIndex: -1, //当前处在哪个节点上
  markForm: {
    macAddress: '', //	mac地址
    markProperty: '', //标记属性
    originalNode: '', //原节点
    robotNo: '' //车辆编号
  }, //标记的表单
  mapMarkCarList: [], //标记的车辆列表
  popoverVisible: false, //标记弹窗
  noLocationNumberList: [], //没有排序的库位index
  isShowSortNum: false, //是否显示序号
  actualLocation: {
    x: '',
    y: ''
  }
})

const toolbarClick = async (item) => {
  let type = item.switchType
  if (state.currentItemIndex === -1 && (type === 'move' || type === 'revolve' || type === 'copy')) {
    message.warning('请先选择要操作的对象')
    return
  }

  if (
    type === 'delete' &&
    state.currentDragTarget.index === null &&
    state.currentItemIndex === -1
  ) {
    message.warning('请先选择要操作的对象')
    return
  }

  //粘贴
  if (type === 'paste' && !state.copyMapItem) {
    message.warning('请先复制对象')
    return
  }

  if (
    (type === 'tools' ||
      type === 'text' ||
      type === 'layer' ||
      type === 'grid' ||
      type === 'showSortNum') &&
    toolbarSwitchType.value === type
  ) {
    toolbarSwitchType.value = ''
  } else {
    toolbarSwitchType.value = type
  }

  //鼠标样式的问题
  if (toolbarSwitchType.value !== 'text') {
    state.cursorStyle = `auto`
    state.textFormToolShow = false
    state.showInputBox = false
    state.inputBoxValue = ''
  }
  if (
    toolbarSwitchType.value === 'generateLine' ||
    toolbarSwitchType.value === 'createLineLibrary' ||
    toolbarSwitchType.value === 'createRegion'
  ) {
    state.cursorStyle = 'crosshair'
  } else {
    state.cursorStyle = `auto`
  }

  //工具切换 不适用框选的 要把框选的信息都删掉
  if (
    toolbarSwitchType.value !== 'createLineLibrary' &&
    toolbarSwitchType.value !== 'createRegion'
  ) {
    state.drawSelectionAreaShow = false
    state.allDrawSelectionAreaBox = []
    state.drawSelectionPointList = []
  }
  //非测距
  if (toolbarSwitchType.value !== 'ranging') {
    state.measureDistancesPoints = [] // 清空存储点击的点位
    state.measureDistancesNum = 0 // 清空存储两点之间的距离
  }

  //禁止操作 在框选测距等操作时，禁止所有拖动等操作
  if (
    toolbarSwitchType.value === 'drawNodes' ||
    toolbarSwitchType.value === 'editNode' ||
    toolbarSwitchType.value === 'clickDrawRoute' ||
    toolbarSwitchType.value === 'drawRoute' ||
    toolbarSwitchType.value === 'createLineLibrary' ||
    toolbarSwitchType.value === 'createRegion' ||
    toolbarSwitchType.value === 'bulkDelete'
  ) {
    state.prohibitedOperation = true
  } else {
    state.prohibitedOperation = false
  }

  switch (type) {
    case 'open':
      // 打开
      break
    case 'save':
      //保存
      await message.confirm('请确认是否保存？')
      saveMap()
      break
    case 'saveAs':
      //另存为 存为json文件 无法直接访问用户的文件系统 不能选择存在那个文件夹里面
      const jsonString = JSON.stringify(state.allHistoryList[state.currentIndex], null, 2)
      const blob = new Blob([jsonString], { type: 'application/json' })
      const url = URL.createObjectURL(blob)

      const a = document.createElement('a')
      a.href = url
      a.download = 'mapJson.json'
      document.body.appendChild(a)
      a.click()
      document.body.removeChild(a)
      URL.revokeObjectURL(url)

      message.success('下载成功')
      break
    case 'choose':
      //选择
      break
    case 'move':
      //移动
      console.log(state.allMapPointInfo[state.currentItemIndex])
      state.moveForm.locationX = Number(state.allMapPointInfo[state.currentItemIndex].locationX)
      state.moveForm.locationY = Number(state.allMapPointInfo[state.currentItemIndex].locationY)
      break
    case 'revolve':
      state.rotationForm.angle = Number(state.allMapPointInfo[state.currentItemIndex]?.angle) || 0
      break
    case 'copy':
      //复制
      replicationNode()
      break
    case 'paste':
      //粘贴
      pasteNode()
      break
    case 'delete':
      //删除
      if (state.currentItemIndex !== -1) {
        let deleteId = state.allMapPointInfo[state.currentItemIndex].id
        // 点删除之后 跟点相关的路线都要删除
        state.mapRouteList = state.mapRouteList.filter(
          (item) => item.startingPointId !== deleteId && item.endPointId !== deleteId
        )
        state.allMapPointInfo.splice(state.currentItemIndex, 1)
        //恢复index
        state.currentItemIndex = -1
      }
      if (state.currentDragTarget.index !== null) {
        state.mapRouteList.splice(state.currentDragTarget.index, 1)
        state.currentDragTarget.index = null
      }
      addEditHistory()
      setTimeout(() => {
        toolbarSwitchType.value = ''
      }, 200)
      break
    case 'tools':
      //工具
      if (toolbarSwitchType.value === 'tools') {
        state.isShowToolbar = true
        item.isActive = true
      } else {
        state.isShowToolbar = false
        item.isActive = false
      }
      break
    case 'lineLibrary':
      // 线库
      break
    case 'region':
      // 区域
      break
    case 'createLineLibrary':
      // 生成线库
      state.isShowSortNum = false
      state.rightToolList.forEach((item) => {
        if (item.switchType === 'showSortNum') {
          item.isActive = false
        }
      })
      break
    case 'createRegion':
      // 生成区域
      break
    case 'lineLibraryManage':
      // 线库管理
      removeEventListener() //移除监听
      lineLibraryManagementDialogRef.value.open()
      break
    case 'regionManage':
      removeEventListener() //移除监听
      itemAreaManagementDialogRef.value.open()
      // 区域管理
      break
    case 'text':
      //文字
      if (toolbarSwitchType.value === 'text') {
        state.textFormToolShow = true
        state.cursorStyle = `url('${cursorCollection.input}'),auto`
      } else {
        state.cursorStyle = `auto`
        state.textFormToolShow = false
        state.showInputBox = false
        state.inputBoxValue = ''
      }
      break
    case 'ranging':
      // 测距
      break
    case 'layer':
      //图层
      if (toolbarSwitchType.value === 'layer') {
        state.isShowLayer = true
        item.isActive = true
      } else {
        state.isShowLayer = false
        item.isActive = false
      }
      break
    case 'marker':
      // 标记
      mapMark()
      break
    case 'grid':
      //网格
      if (toolbarSwitchType.value === 'grid') {
        state.isShowGrid = true
        item.isActive = true
      } else {
        state.isShowGrid = false
        item.isActive = false
      }
      break
    case 'larger':
      //放大
      if (state.imageChangeMultiple < 4) {
        state.imageChangeMultiple += 0.2
      } else {
        message.warning('不能在放大了')
      }
      break
    case 'smaller':
      //缩小
      if (state.imageChangeMultiple > 0.2) {
        state.imageChangeMultiple -= 0.2
      } else {
        message.warning('不能在缩小了')
      }
      break
    case 'withdraw':
      //上一步
      backPreviousStep()
      break
    case 'next':
      //下一步
      backNextStep()
      break
    case 'drawNodes':
      //新增节点
      break
    case 'editNode':
      // 编辑节点
      break
    case 'drawRoute':
      //新增路线
      break
    case 'editRoute':
      // 编辑路线
      break
    case 'equipment':
      // 设备
      let equipmentList = state.allMapPointInfo.filter((item) => {
        return item.type === 3
      })
      removeEventListener() //移除监听
      equipmentToolDialogRef.value.open(equipmentList)
      break
    case 'generateLine':
      // 生成直线
      break
    case 'bulkDelete':
      // 批量删除
      break
    case 'showSortNum':
      // 显示节点序号
      //网格
      if (toolbarSwitchType.value === 'showSortNum') {
        state.isShowSortNum = true
        item.isActive = true
      } else {
        state.isShowSortNum = false
        item.isActive = false
      }
      break
  }
}

//复制
const replicationNode = () => {
  let copyMapItem = state.allMapPointInfo[state.currentItemIndex]

  if (copyMapItem.type === 3) {
    message.warning('设备不能复制！')
    return
  }

  let locationX = Number(copyMapItem.locationX) + 20
  let locationY = Number(copyMapItem.locationY) + 20
  let actualPoint = disposeEventPoint(locationX, locationY)
  if (copyMapItem.dataList.length > 0) {
    copyMapItem.dataList.forEach((item) => {
      delete item.id
      delete item.locationNo
      delete item.mapItemId
    })
    copyMapItem.dataJson = JSON.stringify(copyMapItem.dataList)
  }

  if (copyMapItem.dataObj && JSON.stringify(copyMapItem.dataObj) !== '{}') {
    delete copyMapItem.dataObj.id
    delete copyMapItem.dataObj.positionMapItemId
    copyMapItem.dataJson = JSON.stringify(copyMapItem.dataObj)
  }
  state.copyMapItem = {
    positionMapId: copyMapItem.positionMapId,
    locationX: locationX,
    locationY: locationY,
    actualLocationX: actualPoint.actualLocationX,
    actualLocationY: actualPoint.actualLocationY,
    type: copyMapItem.type,
    dataJson: copyMapItem.dataJson || '',
    dataObj: copyMapItem.dataObj || {},
    dataList: copyMapItem.dataList || [],
    locationDeep: copyMapItem.locationDeep,
    locationWide: copyMapItem.locationWide,
    locationDeepPx: copyMapItem.locationDeepPx,
    locationWidePx: copyMapItem.locationWidePx,
    draggable: copyMapItem.draggable,
    resizable: copyMapItem.resizable,
    rotatable: copyMapItem.rotatable,
    lockAspectRatio: copyMapItem.lockAspectRatio,
    layerSelectionShow: copyMapItem.layerSelectionShow,
    mapImageUrl: copyMapItem.mapImageUrl,
    locationYaw: copyMapItem.locationYaw,
    areaId: null,
    locationNumber: null
  }
  message.success('复制成功')
}
//粘贴
const pasteNode = () => {
  let copyObj = JSON.parse(JSON.stringify(state.copyMapItem))
  state.allMapPointInfo.push(copyObj)
  message.success('粘贴成功')
  addEditHistory()
}
//移动工具表单提交
const moveFormSubmit = async () => {
  state.allMapPointInfo[state.currentItemIndex].locationX = Number(state.moveForm.locationX)
  state.allMapPointInfo[state.currentItemIndex].locationY = Number(state.moveForm.locationY)
  addEditHistory()
}
//旋转工具表单提交
const rotationFormSubmit = () => {
  state.allMapPointInfo[state.currentItemIndex].angle = state.rotationForm.angle
  addEditHistory()
}

//标记
const mapMark = async () => {
  state.mapMarkCarList = await MapApi.getListByMapId(imgBgObj.positionMapId)

  if (state.currentItemIndex != -1) {
    let item = state.allMapPointInfo[state.currentItemIndex]
    state.markForm.originalNode = `[${item.locationX},${item.locationY}]`
    if (item.type == 1) {
      state.markForm.markProperty = '路径点'
    } else if (item.type == 2) {
      state.markForm.markProperty = '库位点'
    } else if (item.type == 3) {
      state.markForm.markProperty = '设备点'
    } else if (item.type == 4) {
      state.markForm.markProperty = '停车点'
    } else if (item.type == 5) {
      state.markForm.markProperty = '区域变更点'
    } else if (item.type == 6) {
      state.markForm.markProperty = '等待点'
    }
  } else {
    state.markForm.markProperty = ''
    state.markForm.originalNode = ''
  }
  state.popoverVisible = true
}
//标记提交
const macAddressChange = (e) => {
  const targetItem = state.mapMarkCarList.find((item) => item.macAddress === e)
  if (targetItem) {
    state.markForm.robotNo = targetItem.robotNo
  }
}
//取消标记
const markFormCancel = () => {
  state.popoverVisible = false
  state.markForm.markProperty = ''
  state.markForm.originalNode = ''
  state.markForm.macAddress = ''
  state.markForm.robotNo = ''
}
//确认标记
const markFormSubmit = async () => {
  if (!state.markForm.macAddress) {
    message.warning('请选择车辆')
    return
  }
  let res = await MapApi.getAGVPointInformation(state.markForm.macAddress)
  if (res) {
    let content = JSON.parse(res.content)
    let point = JSON.parse(content[state.markForm.robotNo]) //标记传过来的数据
    let pointPx = convertActualToBrowser(point.x, point.y)
    let actualPoint = disposeEventPoint(pointPx.x, pointPx.y)

    if (state.currentItemIndex !== -1) {
      state.allMapPointInfo[state.currentItemIndex].locationX = pointPx.x
      state.allMapPointInfo[state.currentItemIndex].locationY = pointPx.y
      state.allMapPointInfo[state.currentItemIndex].actualLocationX = actualPoint.actualLocationX
      state.allMapPointInfo[state.currentItemIndex].actualLocationY = actualPoint.actualLocationY

      //更改路线里的
      let item = state.allMapPointInfo[state.currentItemIndex]
      state.mapRouteList.forEach((route) => {
        if (item.id === route.startingPointId) {
          route.startPointX = pointPx.x
          route.startPointY = pointPx.y
          route.beginHigh = Number(item.locationDeepPx)
          route.beginWidth = Number(item.locationWidePx)
          route.actualStartPointX = actualPoint.actualLocationX
          route.actualStartPointY = actualPoint.actualLocationY
        }
        if (item.id === route.endPointId) {
          route.endPointX = pointPx.x
          route.endPointY = pointPx.y
          route.endHigh = Number(item.locationDeepPx)
          route.endWidth = Number(item.locationWidePx)
          route.actualEndPointX = actualPoint.actualLocationX
          route.actualEndPointY = actualPoint.actualLocationY
        }
      })

      addEditHistory()
    } else {
      //新增一个节点
      state.allMapPointInfo.push({
        positionMapId: imgBgObj.positionMapId, //地图的id
        layerSelectionShow: true,
        locationX: pointPx.x,
        locationY: pointPx.y,
        actualLocationX: actualPoint.actualLocationX,
        actualLocationY: actualPoint.actualLocationY,
        locationDeep: 40,
        locationWide: 40,
        locationDeepPx: 8,
        locationWidePx: 8,
        angle: 0,
        draggable: true,
        resizable: true,
        rotatable: false,
        lockAspectRatio: false, //横纵比
        mapImageUrl: '',
        type: 1, //默认类型1 路径节点
        dataList: [], //存库位的
        dataObj: {}, //存 设备点 停车点 文字
        locationYaw: 0 //弧度
      })
      addEditHistory()
    }
  } else {
    message.warning('未采集到该AGV点位信息')
  }
  state.popoverVisible = false
}

//鼠标拖动绘制节点
// 从点开始绘制
const startFromPoint = (index, event) => {
  if (toolbarSwitchType.value === 'clickDrawRoute') {
    let list = state.allMapPointInfo
    const point = list[index]
    if (point.id) {
      state.startDrawPoint = point //开始点
      state.startDrawPointIndex = index
      state.isDrawing = true
      event.preventDefault() // 防止默认行为
    } else {
      message.warning('选择的节点未保存')
      // 重置状态
      state.startDrawPointIndex = -1 // 起始点的索引
      state.startDrawPoint = null
      state.isDrawing = false
      state.currentDrawX = 0
      state.currentDrawY = 0
    }
  }
}
//开始框选绘制
const startDrawSelection = (event) => {
  if (
    toolbarSwitchType.value === 'createLineLibrary' ||
    toolbarSwitchType.value === 'createRegion' ||
    toolbarSwitchType.value === 'drawRoute' ||
    toolbarSwitchType.value == 'generateLine' ||
    toolbarSwitchType.value === 'bulkDelete'
  ) {
    const backgroundRect = mapBackgroundRef.value.getBoundingClientRect()

    const x = disposeEventPoints(event).x
    const y = disposeEventPoints(event).y

    // 确保点击在背景区域内
    if (x >= 0 && x <= backgroundRect.width && y >= 0 && y <= backgroundRect.height) {
      state.drawSelectionAreaShow = true
      state.drawSelectionStartPoint = { x: x, y: y }
      state.drawSelectionAreaBox = { x: x, y: y, width: 0, height: 0 }
    }
    event.preventDefault() // 阻止默认行为（避免选中图片或文本）
  }
}
// 更新框选区域
const updateDrawSelection = (event) => {
  if (
    toolbarSwitchType.value === 'createLineLibrary' ||
    toolbarSwitchType.value === 'createRegion' ||
    toolbarSwitchType.value === 'drawRoute' ||
    toolbarSwitchType.value === 'generateLine' ||
    toolbarSwitchType.value === 'bulkDelete'
  ) {
    if (state.drawSelectionAreaShow) {
      const x = disposeEventPoints(event).x
      const y = disposeEventPoints(event).y

      state.drawSelectionAreaBox = {
        x: Math.min(state.drawSelectionStartPoint.x, x),
        y: Math.min(state.drawSelectionStartPoint.y, y),
        width: Math.abs(Number(x) - Number(state.drawSelectionStartPoint.x)),
        height: Math.abs(Number(y) - Number(state.drawSelectionStartPoint.y))
      }
    }
    event.preventDefault() // 阻止默认行为（避免选中图片或文本）
  }
  if (toolbarSwitchType.value === 'clickDrawRoute') {
    // 实时绘制
    if (state.isDrawing) {
      const x = disposeEventPoints(event).x
      const y = disposeEventPoints(event).y

      state.currentDrawX = x
      state.currentDrawY = y
    }
    event.preventDefault() // 阻止默认行为（避免选中图片或文本）
  }
}
//结束框选绘制
const endDrawSelection = (event) => {
  if (
    toolbarSwitchType.value === 'createLineLibrary' ||
    toolbarSwitchType.value === 'createRegion' ||
    toolbarSwitchType.value === 'drawRoute' ||
    toolbarSwitchType.value === 'generateLine' ||
    toolbarSwitchType.value === 'bulkDelete'
  ) {
    state.drawSelectionAreaShow = false
    state.allDrawSelectionAreaBox.push({ ...state.drawSelectionAreaBox })
    state.drawSelectionAreaBox = { x: 0, y: 0, width: 0, height: 0 }
    event.preventDefault() // 阻止默认行为（避免选中图片或文本）
    return
  }
  if (toolbarSwitchType.value === 'clickDrawRoute') {
    if (state.isDrawing) {
      // 找到最近的终点
      const endPointIndex = findClosestPoint(state.currentDrawX, state.currentDrawY)

      if (endPointIndex !== null && endPointIndex !== state.startDrawPointIndex) {
        let list = state.allMapPointInfo
        const endPoint = list[endPointIndex]

        //先判断节点有没有保存
        if (!endPoint.id) {
          message.warning('选择的节点未保存')
          // 重置状态
          state.startDrawPointIndex = -1 // 起始点的索引
          state.startDrawPoint = null
          state.isDrawing = false
          state.currentDrawX = 0
          state.currentDrawY = 0
          return
        }

        const newLine = {
          startPointX: state.startDrawPoint.locationX,
          startPointY: state.startDrawPoint.locationY,
          endPointX: endPoint.locationX,
          endPointY: endPoint.locationY
        }
        // 检查是否已存在相同的直线
        const isDuplicate = state.mapRouteList.some(
          (line) =>
            (line.startPointX === newLine.startPointX &&
              line.startPointY === newLine.startPointY &&
              line.endPointX === newLine.endPointX &&
              line.endPointY === newLine.endPointY) ||
            (line.startPointX === newLine.endPointX &&
              line.startPointY === newLine.endPointY &&
              line.endPointX === newLine.startPointX &&
              line.endPointY === newLine.startPointY)
        )
        if (isDuplicate) {
          message.warning('此路线已存在')
        } else {
          // 保存当前直线
          state.mapRouteList.push({
            isSelected: false, //是否选中
            startingPointId: state.startDrawPoint.id,
            endPointId: endPoint.id,
            startPointX: state.startDrawPoint.locationX, //开始点
            startPointY: state.startDrawPoint.locationY, //开始点
            endPointX: endPoint.locationX, //结束点
            endPointY: endPoint.locationY, //结束点
            actualStartPointX: state.startDrawPoint.actualLocationX, //实际开始点位x轴
            actualStartPointY: state.startDrawPoint.actualLocationY, //实际开始点位y轴
            actualEndPointX: endPoint.actualLocationX, //实际结束点位x轴
            actualEndPointY: endPoint.actualLocationY, //实际结束点位y轴
            actualBeginControlX: '', //实际开始控制点x轴
            actualBeginControlY: '', //实际开始控制点y轴
            actualEndControlX: '', //实际结束控制点x轴
            actualEndControlY: '', //实际结束控制点y轴
            beginControlX: 0, //开始控制点x轴
            beginControlY: 0, //开始控制点y轴
            endControlX: 0, //结束控制点x轴
            endControlY: 0, //结束控制点y轴
            expansionZoneFront: 0, //膨胀区域前
            expansionZoneAfter: 0, //膨胀区域后
            expansionZoneLeft: 0, //	膨胀区域左
            expansionZoneRight: 0, //膨胀区域右
            method: 0, //行走方法 0.直线 1.上左曲线2.上右曲线3.下左曲线 4.下右曲线
            direction: 2, //方向 1.单向 2.双向,
            forwardSpeedLimit: 1.5, //正向限速
            reverseSpeedLimit: 0.4, //	反向限速
            toward: 0, //	车头朝向( 0:正正 1:正反 2:反正 3:反反)
            beginWidth: state.startDrawPoint.locationWidePx, //起点宽
            beginHigh: state.startDrawPoint.locationDeepPx, //	起点高
            endWidth: endPoint.locationWidePx, //	终点宽
            endHigh: endPoint.locationDeepPx, //	终点高
            startingSortNum: state.startDrawPoint.sortNum,
            endPointSortNum: endPoint.sortNum
          })
          addEditHistory()
        }
      }
      // 重置状态
      state.startDrawPointIndex = -1 // 起始点的索引
      state.startDrawPoint = null
      state.isDrawing = false
      state.currentDrawX = 0
      state.currentDrawY = 0
    }
    event.preventDefault() // 阻止默认行为（避免选中图片或文本）
    return
  }
}
// 找到最近的点
const findClosestPoint = (x, y) => {
  let minDistance = Infinity
  let closestIndex = null
  let list = state.allMapPointInfo
  list.forEach((point, index) => {
    const distance = Math.sqrt((point.locationX - x) ** 2 + (point.locationY - y) ** 2)
    if (distance < minDistance && distance < point.locationWide) {
      // 10 是点的捕捉范围
      minDistance = distance
      closestIndex = index
    }
  })
  return closestIndex
}
//点击区域
const clickDrawSelectionArea = () => {
  let points = state.allMapPointInfo

  state.drawSelectionPointList = []
  state.allDrawSelectionAreaBox.forEach((box) => {
    points.forEach((point) => {
      if (
        point.locationX >= box.x &&
        point.locationX <= box.x + box.width &&
        point.locationY >= box.y &&
        point.locationY <= box.y + box.height
      ) {
        state.drawSelectionPointList.push(point)
      }
    })
  })

  // 清空框选区域
  state.allDrawSelectionAreaBox = []
  //去重
  state.drawSelectionPointList = deduplicateArrayById(state.drawSelectionPointList)
  //只要库位的
  let binLocation = state.drawSelectionPointList.filter((item) => item.type === 2)
  //所以类型的
  let routeList = state.drawSelectionPointList

  let isHaveId = binLocation.every((item) => {
    item.id
  })

  //线库
  if (toolbarSwitchType.value === 'createLineLibrary') {
    //线库
    if (binLocation.length < 2) {
      message.warning('至少选择两个库位')
      return
    }

    // if (!isStraightLine(binLocation)) {
    //   message.warning('您选择的库位不在一条直线上')
    //   return
    // }

    let isHaveId = binLocation.every((item) => {
      return item.id
    })
    if (!isHaveId) {
      message.warning('您选择的库位存在未保存的')
      return
    }

    //判断线库的排序是不是一样
    const locationNumbers = findDuplicateLocationIds(binLocation)
    if (locationNumbers.length > 0) {
      message.warning('您选择的库位的序号不能重复')
      return
    }

    removeEventListener() //移除监听
    lineLibrarySettingDialogRef.value.open(binLocation)
  }
  //区域
  if (toolbarSwitchType.value === 'createRegion') {
    if (binLocation.length < 1) {
      message.warning('至少选择两个库位')
      return
    }
    let isHaveId = binLocation.every((item) => {
      return item.id
    })
    if (!isHaveId) {
      message.warning('您选择的库位存在未保存的')
      return
    }
    removeEventListener() //移除监听
    itemAreaSettingDialogRef.value.open(binLocation)
  }
  //绘制直线
  if (toolbarSwitchType.value === 'drawRoute') {
    if (routeList.length !== 2) {
      message.warning('只能选择两个路径点')
      return
    }
    let isHaveId = routeList.every((item) => {
      return item.id
    })
    if (!isHaveId) {
      message.warning('您选择的路径点存在未保存的')
      return
    }
    let curve = {
      isSelected: false, //是否选中
      startingPointId: routeList[0].id,
      endPointId: routeList[1].id,
      startPointX: routeList[0].locationX, //开始点
      startPointY: routeList[0].locationY, //开始点
      endPointX: routeList[1].locationX, //结束点
      endPointY: routeList[1].locationY, //结束点
      actualStartPointX: routeList[0].actualLocationX, //实际开始点位x轴
      actualStartPointY: routeList[0].actualLocationY, //实际开始点位y轴
      actualEndPointX: routeList[1].actualLocationX, //实际结束点位x轴
      actualEndPointY: routeList[1].actualLocationY, //实际结束点位y轴
      actualBeginControlX: '', //实际开始控制点x轴
      actualBeginControlY: '', //实际开始控制点y轴
      actualEndControlX: '', //实际结束控制点x轴
      actualEndControlY: '', //实际结束控制点y轴
      beginControlX: 0, //开始控制点x轴
      beginControlY: 0, //开始控制点y轴
      endControlX: 0, //结束控制点x轴
      endControlY: 0, //结束控制点y轴
      expansionZoneFront: 0, //膨胀区域前
      expansionZoneAfter: 0, //膨胀区域后
      expansionZoneLeft: 0, //	膨胀区域左
      expansionZoneRight: 0, //膨胀区域右
      method: 0, //行走方法 0.直线 1.上左曲线2.上右曲线3.下左曲线 4.下右曲线
      direction: 2, //方向 1.单向 2.双向,
      forwardSpeedLimit: 1.5, //正向限速
      reverseSpeedLimit: 0.4, //	反向限速
      toward: 0, //	车头朝向( 0:正正 1:正反 2:反正 3:反反)
      beginWidth: routeList[0].locationWidePx, //起点宽
      beginHigh: routeList[0].locationDeepPx, //	起点高
      endWidth: routeList[1].locationWidePx, //	终点宽
      endHigh: routeList[1].locationDeepPx //	终点高
    }
    state.selectedCurve = curve
    state.mapRouteList.push(curve)
    addEditHistory()
  }
  //生成直线
  if (toolbarSwitchType.value === 'generateLine') {
    if (routeList.length < 3) {
      message.warning('至少框选三个点')
      return
    }
    let isHaveId = routeList.every((item) => {
      return item.id
    })
    if (!isHaveId) {
      message.warning('您选择的路径点存在未保存的')
      return
    }
    GenerateStraightLinesDialogRef.value.open(routeList)
  }
  //批量删除
  if (toolbarSwitchType.value === 'bulkDelete') {
    if (routeList.length < 1) {
      message.warning('至少选择一个点')
      return
    }
    //删除的节点id合集
    const routeIds = routeList.map((route) => route.id)
    //在数组中去除这些节点
    state.allMapPointInfo = state.allMapPointInfo.filter((item) => {
      return !routeIds.includes(item.id)
    })
    //将路线中的删除
    state.mapRouteList = state.mapRouteList.filter((item) => {
      return !routeIds.includes(item.startingPointId) && !routeIds.includes(item.endPointId)
    })
    state.currentItemIndex = -1
    addEditHistory()
  }
}
//生成直线 选择完成开始点和结束点
const GenerateStraightLinesSubmit = (pointList, form) => {
  const list = mapPointsToLine(pointList, form.startPointId, form.endPointId)
  const idNameMap = {}
  list.forEach((item) => {
    idNameMap[item.id] = item
  })
  // 遍历第二个数组，更新 name
  state.allMapPointInfo.forEach((item) => {
    if (idNameMap[item.id]) {
      let actualPoint = disposeEventPoint(
        idNameMap[item.id].locationX,
        idNameMap[item.id].locationY
      )
      item.locationX = idNameMap[item.id].locationX
      item.locationY = idNameMap[item.id].locationY
      item.actualLocationX = actualPoint.actualLocationX
      item.actualLocationY = actualPoint.actualLocationY
    }
  })
  state.mapRouteList.forEach((item) => {
    if (idNameMap[item.startingPointId]) {
      let actualPoint = disposeEventPoint(
        idNameMap[item.startingPointId].locationX,
        idNameMap[item.startingPointId].locationY
      )
      item.startPointX = idNameMap[item.startingPointId].locationX
      item.startPointY = idNameMap[item.startingPointId].locationY
      item.actualStartPointX = actualPoint.actualLocationX
      item.actualStartPointY = actualPoint.actualLocationY
    }
    if (idNameMap[item.endPointId]) {
      let actualPoint = disposeEventPoint(
        idNameMap[item.endPointId].locationX,
        idNameMap[item.endPointId].locationY
      )
      item.endPointX = idNameMap[item.endPointId].locationX
      item.endPointY = idNameMap[item.endPointId].locationY
      item.actualEndPointX = actualPoint.actualLocationX
      item.actualEndPointY = actualPoint.actualLocationY
    }
  })
  addEditHistory()
}
//去重
const deduplicateArrayById = (arr) => {
  const idSet = new Set()
  return arr.filter((item) => {
    if (idSet.has(item.id)) {
      return false
    }
    idSet.add(item.id)
    return true
  })
}
//返回生成线库时 排序相同项的id
const findDuplicateLocationIds = (data) => {
  const locationMap = {}

  data.forEach((item) => {
    if (!locationMap[item.locationNumber]) {
      locationMap[item.locationNumber] = []
    }
    locationMap[item.locationNumber].push(item.id)
  })

  return Object.values(locationMap).filter((ids) => ids.length > 1)
}

//将一个数组中的点位 按照第一个和最后一个排成一条直线
const mapPointsToLine = (points, startPointId, endPointId) => {
  const startPoint = points.find((point) => point.id === startPointId)
  const endPoint = points.find((point) => point.id === endPointId)

  if (!startPoint || !endPoint) {
    message.warning('选择的点位有误')
    return
  }

  const dx = endPoint.locationX - startPoint.locationX
  const dy = endPoint.locationY - startPoint.locationY
  const length = Math.sqrt(dx * dx + dy * dy)

  return points.map((point) => {
    if (point.id === startPointId || point.id === endPointId) {
      return point
    }

    const vx = point.locationX - startPoint.locationX
    const vy = point.locationY - startPoint.locationY
    const dotProduct = vx * dx + vy * dy
    const projectionLength = dotProduct / length

    const t = Math.max(0, Math.min(1, projectionLength / length))

    const newX = startPoint.locationX + t * dx
    const newY = startPoint.locationY + t * dy

    return {
      ...point,
      locationX: newX,
      locationY: newY
    }
  })

  // const dx = startPoint.locationX - endPoint.locationX
  // const dy = startPoint.locationY - endPoint.locationY

  // // 处理垂直直线的情况
  // if (dx === 0) {
  //   return points.map((point) => {
  //     if (point === endPoint || point === startPoint) {
  //       return point
  //     }
  //     return {
  //       ...point,
  //       locationX: endPoint.locationX
  //     }
  //   })
  // }

  // const slope = dy / dx
  // const intercept = endPoint.locationY - slope * endPoint.locationX

  // return points.map((point) => {
  //   if (point === endPoint || point === startPoint) {
  //     return point
  //   }
  //   const newY = slope * point.locationX + intercept
  //   return {
  //     ...point,
  //     locationY: newY
  //   }
  // })
}

//计算是不是在同一条直线的
const isStraightLine = (binLocation) => {
  if (binLocation.length <= 2) {
    return true // 两个点一定在一条直线上
  }

  const firstPoint = binLocation[0]
  const secondPoint = binLocation[1]

  // 检查是否垂直直线（所有 x 相同）
  const isVertical = binLocation.every(
    (point) => Number(point.locationX) === Number(firstPoint.locationX)
  )
  if (isVertical) {
    return true
  }

  // 检查是否水平直线（所有 y 相同）
  const isHorizontal = binLocation.every(
    (point) => Number(point.locationY) === Number(firstPoint.locationY)
  )
  if (isHorizontal) {
    return true
  }

  // 计算斜率
  const slope =
    Number(secondPoint.locationY) -
    Number(firstPoint.locationY) / (Number(secondPoint.locationX) - Number(firstPoint.locationX))

  // 检查所有点是否在同一条斜线上
  return binLocation.every((point) => {
    const currentSlope =
      (Number(point.locationY) - Number(firstPoint.locationY)) /
      (Number(point.locationX) - Number(firstPoint.locationX))
    return Math.abs(currentSlope - slope) < Number.EPSILON // 处理浮点数精度问题
  })
}
//三阶贝塞尔曲线
// 开始拖拽
const startDrag = (item, index, type) => {
  state.currentDragTarget = { index, type }
  window.addEventListener('mousemove', handleDrag)
  window.addEventListener('mouseup', endDrag)
}
// 处理拖动事件
const handleDrag = (event) => {
  let x = disposeEventPoints(event).x
  let y = disposeEventPoints(event).y

  if (state.currentDragTarget.index !== null) {
    const curve = state.mapRouteList[state.currentDragTarget.index]

    // 确保控制点不超出盒子范围
    x = Math.max(0, Math.min(x, imgBgObj.width))
    y = Math.max(0, Math.min(y, imgBgObj.height))

    if (state.currentDragTarget.type === 'start') {
      curve.beginControlX = x
      curve.beginControlY = y
    } else {
      curve.endControlX = x
      curve.endControlY = y
    }
  }
}
// 结束拖动
const endDrag = (event) => {
  const curve = state.mapRouteList[state.currentDragTarget.index]
  let actualBeginControl = disposeEventPoint(curve.beginControlX, curve.beginControlY)
  let actualEndControl = disposeEventPoint(curve.endControlX, curve.endControlY)

  curve.actualBeginControlX = actualBeginControl.actualLocationX
  curve.actualBeginControlY = actualBeginControl.actualLocationY

  curve.actualEndControlX = actualEndControl.actualLocationX
  curve.actualEndControlY = actualEndControl.actualLocationY

  addEditHistory()

  state.currentDragTarget.type = null
  window.removeEventListener('mousemove', handleDrag)
  window.removeEventListener('mouseup', endDrag)
}
// 获取曲线的路径
const getCurvePath = (curve) => {
  let startPointX = Number(curve.startPointX)
  let startPointY = Number(curve.startPointY)
  let endPointX = Number(curve.endPointX)
  let endPointY = Number(curve.endPointY)
  let path = `M ${startPointX} ${startPointY} C ${curve.beginControlX} ${curve.beginControlY}, ${curve.endControlX} ${curve.endControlY}, ${endPointX} ${endPointY}`

  curve.curvePath = path
  return path
}
// 编辑路线
const handleChooseRoute = (item, index) => {
  state.mapRouteList.forEach((curve, i) => {
    curve.isSelected = i === index
  })
  state.selectedCurve = item
  state.currentDragTarget.index = index
  //让节点不选中
  state.currentItemIndex = -1

  if (toolbarSwitchType.value === 'editRoute') {
    removeEventListener() //移除监听
    editMapRouteDialogRef.value.open(JSON.parse(JSON.stringify(item)))
  }
}
//编辑路线成功
const editMapRouteDialogSubmit = (form) => {
  state.mapRouteList[state.currentDragTarget.index] = form

  //路线位置改变 通知路径里面的节点也改变
  state.mapRouteList.forEach((item) => {
    if (form.startingPointId === item.startingPointId) {
      item.startPointX = form.startPointX
      item.startPointY = form.startPointY
      item.beginHigh = Number(form.beginHigh)
      item.beginWidth = Number(form.beginWidth)
      item.actualStartPointX = disposeEventPoint(form.startPointX, form.startPointY).actualLocationX
      item.actualStartPointY = disposeEventPoint(form.startPointX, form.startPointY).actualLocationY
    }
    if (form.endPointId === item.endPointId) {
      item.endPointX = form.endPointX
      item.endPointY = form.endPointY
      item.endHigh = Number(form.endHigh)
      item.endWidth = Number(form.endWidth)
      item.actualEndPointX = disposeEventPoint(form.endPointX, form.endPointY).actualLocationX
      item.actualEndPointY = disposeEventPoint(form.endPointX, form.endPointY).actualLocationY
    }
  })
  state.allMapPointInfo.forEach((item) => {
    if (item.id === form.startingPointId) {
      item.locationX = form.startPointX
      item.locationY = form.startPointY
      item.actualLocationX = disposeEventPoint(form.startPointX, form.startPointY).actualLocationX
      item.actualLocationY = disposeEventPoint(form.startPointX, form.startPointY).actualLocationY
    }
    if (item.id === form.endPointId) {
      item.locationX = form.endPointX
      item.locationY = form.endPointY
      item.actualLocationX = disposeEventPoint(form.endPointX, form.endPointY).actualLocationX
      item.actualLocationY = disposeEventPoint(form.endPointX, form.endPointY).actualLocationY
    }
  })
  //增加一条历史记录
  addEditHistory() //重新监听键盘事件
}
//测距相关
// 计算连线的样式
const rangingLineStyle = computed(() => {
  if (state.measureDistancesPoints.length === 2) {
    const [point1, point2] = state.measureDistancesPoints
    const length = Math.sqrt(Math.pow(point2.x - point1.x, 2) + Math.pow(point2.y - point1.y, 2))
    const angle = (Math.atan2(point2.y - point1.y, point2.x - point1.x) * 180) / Math.PI
    return {
      position: 'absolute',
      left: `${point1.x}px`,
      top: `${point1.y}px`,
      width: `${length}px`,
      height: '2px',
      backgroundColor: 'red',
      transform: `rotate(${angle}deg)`,
      transformOrigin: '0 0'
    }
  }
  return {}
})

// 计算距离信息的样式（显示在连线中间，并根据角度调整文字方向）
const rangingTextStyle = computed(() => {
  if (state.measureDistancesPoints.length === 2) {
    const [point1, point2] = state.measureDistancesPoints
    const midX = (point1.x + point2.x) / 2
    const midY = (point1.y + point2.y) / 2
    const angle = (Math.atan2(point2.y - point1.y, point2.x - point1.x) * 180) / Math.PI

    // 调整文字方向，使其始终易于阅读
    let textRotation = 0
    if (angle > 90 || angle < -90) {
      textRotation = angle + 180 // 翻转文字方向
    } else {
      textRotation = angle
    }

    return {
      position: 'absolute',
      left: `${midX}px`,
      top: `${midY}px`,
      transform: `translate(-50%, -50%) rotate(${textRotation}deg)`,
      backgroundColor: 'rgba(255, 255, 255, 0.8)',
      padding: '2px',
      borderRadius: '4px',
      fontSize: '12px',
      color: 'black',
      whiteSpace: 'nowrap', // 防止文字换行
      pointerEvents: 'none' // 防止文字遮挡点击事件
    }
  }
  return {}
})

// 计算点的样式
const getRangingPointStyle = (point) => ({
  position: 'absolute',
  left: `${point.x - 4}px`,
  top: `${point.y - 4}px`,
  width: '8px',
  height: '8px',
  backgroundColor: 'blue',
  borderRadius: '50%'
})

//计算路线的距离
const calculateRouteLength = (item, type) => {
  const {
    startPointX,
    startPointY,
    endPointX,
    endPointY,
    beginControlX,
    beginControlY,
    endControlX,
    endControlY
  } = item

  if (type == 'line') {
    const dx = startPointX - endPointX
    const dy = startPointY - endPointY
    const length = Math.sqrt(dx * dx + dy * dy) * Number(imgBgObj.resolution)
    return length.toFixed(2)
  } else {
    const steps = 100 // 离散化的步数，步数越多越精确
    let length = 0
    let prevPoint = null

    for (let i = 0; i <= steps; i++) {
      const t = i / steps
      // 三阶贝塞尔曲线公式
      const x =
        (1 - t) ** 3 * startPointX +
        3 * t * (1 - t) ** 2 * beginControlX +
        3 * t ** 2 * (1 - t) * endControlX +
        t ** 3 * endPointX
      const y =
        (1 - t) ** 3 * startPointY +
        3 * t * (1 - t) ** 2 * beginControlY +
        3 * t ** 2 * (1 - t) * endControlY +
        t ** 3 * endPointY
      const currentPoint = [x, y]

      if (prevPoint) {
        const dx = currentPoint[0] - prevPoint[0]
        const dy = currentPoint[1] - prevPoint[1]
        length += Math.sqrt(dx * dx + dy * dy)
      }
      prevPoint = currentPoint
    }
    length = (length * Number(imgBgObj.resolution)).toFixed(2)
    return length
  }
}

// 处理点击事件
const measureDistancesClick = (event) => {
  // 获取点击点相对于整个页面的坐标

  const x = disposeEventPoints(event).x
  const y = disposeEventPoints(event).y

  // 检查点击是否发生在背景区域内
  if (state.measureDistancesPoints.length === 2) {
    // 如果已经有两个点，清空信息
    state.measureDistancesPoints = []
    state.measureDistancesNum = null
  } else {
    // 记录点击的点位（相对于背景区域的坐标）
    const offsetX = x
    const offsetY = y
    state.measureDistancesPoints.push({ x: offsetX, y: offsetY })
    if (state.measureDistancesPoints.length === 2) {
      // 计算两点之间的距离
      const [point1, point2] = state.measureDistancesPoints
      let distancesNum = Math.sqrt(
        Math.pow(point2.x - point1.x, 2) + Math.pow(point2.y - point1.y, 2)
      )
      state.measureDistancesNum = distancesNum * Number(imgBgObj.resolution)
    }
  }
}
//获取扫描图  地图背景相关的信息
const imgBgObj = reactive({
  imgUrl: '',
  positionMapId: '',
  width: '',
  height: '',
  floor: '',
  area: '',
  resolution: 0,
  origin: null
})
//接收参数
const { query } = useRoute() // 查询参数
//获取地图点位
const getMapList = async () => {
  if (!query.mapId) return
  let res = await MapApi.getPositionMap(query.mapId)
  let yamlJson = JSON.parse(res.yamlJson)
  imgBgObj.positionMapId = res.id
  imgBgObj.floor = res.floor
  imgBgObj.area = res.area
  imgBgObj.width = yamlJson.width
  imgBgObj.height = yamlJson.height
  imgBgObj.origin = yamlJson.origin
  imgBgObj.resolution = yamlJson.resolution
  // 调转换成png的接口
  getMapData(imgBgObj)
}
//调转换成png的接口
const getMapData = async (mapInfo) => {
  let data = await MapApi.getPositionMapdDwnloadPngBase64({
    floor: mapInfo.floor,
    area: mapInfo.area
  })
  imgBgObj.imgUrl = data

  //获取节点 路径等信息
  await getAllNodeList()
  await getAllMapRoute()
}
//获取所有的点位 处理七种类型的
const getAllNodeList = async () => {
  let list = await MapApi.getPositionMapItemList({
    positionMapId: imgBgObj.positionMapId
  })
  state.allMapPointInfo = []
  state.currentIndex = 0
  list.forEach((item) => {
    item.layerSelectionShow = true //用于图层
    item.locationX = Number(item.locationX)
    item.locationY = Number(item.locationY)

    if (item.type === 1) {
      item.dataObj = {}
      item.dataList = []
      item.locationDeep = 40
      item.locationWide = 40
      item.draggable = true
      item.resizable = false
      item.rotatable = false
      item.lockAspectRatio = true
    } else if (item.type === 5 || item.type === 6) {
      item.dataObj = {}
      item.dataList = []
      item.locationDeep = 150
      item.locationWide = 150
      item.draggable = true
      item.resizable = false
      item.rotatable = false
      item.lockAspectRatio = true
    } else if (item.type === 2) {
      //库位点
      item.dataList = JSONBigInt({ storeAsString: true }).parse(item.dataJson)
      item.locationDeep = item.dataList[0].locationDeep
      item.locationWide = item.dataList[0].locationWide
      item.areaName = item.dataList[0].areaName || undefined
      item.laneName = item.dataList[0].laneName || undefined
      item.draggable = true
      item.resizable = true
      item.rotatable = false
      item.lockAspectRatio = true
    } else if (item.type === 3) {
      item.dataObj = JSONBigInt({ storeAsString: true }).parse(item.dataJson)
      item.dataList = []
      item.locationDeep = item.dataObj.locationDeep
      item.locationWide = item.dataObj.locationWide
      item.deviceId = item.dataObj.id
      item.deviceNo = item.dataObj.deviceNo
      item.deviceType = item.dataObj.deviceType
      item.mapImageUrl = item.dataObj.mapImageUrl
      item.draggable = true
      item.resizable = true
      item.rotatable = false
      item.lockAspectRatio = true
    } else if (item.type === 4) {
      item.dataObj = JSONBigInt({ storeAsString: true }).parse(item.dataJson)
      item.dataList = []
      item.locationDeep = item.dataObj.locationDeep
      item.locationWide = item.dataObj.locationWide
      item.draggable = true
      item.resizable = true
      item.rotatable = false
      item.lockAspectRatio = true
    } else if (item.type === 7) {
      item.dataObj = JSONBigInt({ storeAsString: true }).parse(item.dataJson)
      item.text = item.dataObj.text
      item.fontColor = item.dataObj.fontColor
      item.fontFamily = item.dataObj.fontFamily
      item.fontSize = item.dataObj.fontSize
      item.angle = item.dataObj.angle
      item.draggable = true
      item.resizable = false
      item.rotatable = true
      item.lockAspectRatio = true
      item.locationDeep = 20
      item.locationWide = 20
    }

    //要将实际的cm改成px
    if (item.locationWide && item.locationDeep) {
      let pxObj = cmConversionPx(item.locationWide, item.locationDeep)
      item.locationWidePx = pxObj.pWidth
      item.locationDeepPx = pxObj.pHeight
    }

    state.allMapPointInfo.push(item)
  })
}
//获取所有的路线
const getAllMapRoute = async () => {
  state.mapRouteList = await MapApi.getPositionMapLineByPositionMapId(imgBgObj.positionMapId)
  state.allHistoryList = []
  state.allHistoryList[0] = {
    allMapPointInfo: JSON.parse(JSON.stringify(state.allMapPointInfo)),
    mapRouteList: JSON.parse(JSON.stringify(state.mapRouteList))
  }
}
//获取设备类型
const getDeviceTypeName = (deviceType) => {
  let list = getIntDictOptions(DICT_TYPE.DEVICE_TYPE)
  let deviceItem = list.find((item) => {
    return item.value == deviceType
  })
  return deviceItem.label
}
//保存地图按钮
const saveMap = async () => {
  //判断是否存在库位未填写排序号
  state.noLocationNumberList = state.allMapPointInfo.reduce((invalidIndexes, item, index) => {
    if (item.type === 2 && !item.locationNumber) {
      invalidIndexes.push(index) // 如果不满足条件，记录索引
    }
    return invalidIndexes
  }, [])

  if (state.noLocationNumberList.length !== 0) {
    state.currentItemIndex = -1
    message.error('存在库位未填写排序号')
    return
  }

  const loading = ElLoading.service({
    lock: true,
    text: '保存中',
    background: 'rgba(255, 255, 255, 0.7)'
  })
  try {
    //节点的保存
    await saveNodeList()
    //路线的保存
    await saveMapRoute()
    //获取新的数据
    await getAllNodeList()
    await getAllMapRoute()
    //关闭loading
    loading.close()
    message.success('保存成功')
  } catch (error) {
    loading.close()
  }
}
//节点的保存
const saveNodeList = async () => {
  let list = state.allMapPointInfo

  list.forEach((item) => {
    if (item.type === 2) {
      // 库位点 类型为数组
      item.dataList.forEach((node) => {
        node.locationDeep = item.locationDeep
        node.locationWide = item.locationWide
      })
      item.dataJson = JSON.stringify(item.dataList)
    } else if (item.type === 3 || item.type === 4) {
      //设备类型
      item.dataObj.locationWide = item.locationWide
      item.dataObj.locationDeep = item.locationDeep
      item.dataJson = JSON.stringify(item.dataObj)
    } else if (item.type === 7) {
      //文字类型
      item.dataObj.positionMapId = imgBgObj.positionMapId
      item.dataObj.text = item.text
      item.dataObj.fontColor = item.fontColor
      item.dataObj.fontType = item.fontType
      item.dataObj.fontFamily = item.fontFamily
      item.dataObj.fontSize = item.fontSize
      item.dataObj.rotatable = item.rotatable
      item.dataObj.angle = item.angle
      //dataJson数据
      item.dataJson = JSON.stringify(item.dataObj)
    }
  })
  await MapApi.batchSaveOrEditOrDelMapItem(imgBgObj.positionMapId, list)
}
//路线的保存
const saveMapRoute = async () => {
  await MapApi.createOrEditOrDelPositionMapLine(imgBgObj.positionMapId, state.mapRouteList)
}
//线库新增 要在库位新增线库信息
const submitLineLibraryFormSuccess = (obj) => {
  state.allMapPointInfo.forEach((item) => {
    if (obj.mapItemIds.includes(item.id)) {
      item.laneId = obj.id
      item.dataList.forEach((node) => {
        node.laneName = obj.laneName
        node.laneId = obj.id
      })
    }
  })
}
//区域新增 要在库位新增区域信息
const itemAreaSettingSubmitSuccess = (obj) => {
  state.allMapPointInfo.forEach((item) => {
    if (obj.mapItemIds.includes(item.id)) {
      item.areaId = obj.id
      item.dataList.forEach((node) => {
        node.areaName = obj.areaName
        node.skuInfo = obj.skuInfo
        node.areaId = obj.id
      })
    }
  })
}
//线库删除 要在库位中删除线库信息
const lineLibraryManagementDelete = (mapItemIds) => {
  state.allMapPointInfo.forEach((item) => {
    if (mapItemIds.includes(item.id)) {
      item.laneId = undefined
      item.dataList.forEach((node) => {
        node.laneName = undefined
        node.laneId = undefined
      })
    }
  })
}
//区域删除 要在库位删除区域信息
const itemAreaManagementDelete = (mapItemIds) => {
  state.allMapPointInfo.forEach((item) => {
    if (mapItemIds.includes(item.id)) {
      item.areaId = undefined
      item.dataList.forEach((node) => {
        node.areaName = undefined
        node.skuInfo = undefined
        node.areaId = undefined
      })
    }
  })
}
//线库编辑 要在库位中编辑线库信息
const lineLibraryManagementEdit = (obj) => {
  console.log(obj)
  state.allMapPointInfo.forEach((item) => {
    if (obj.mapItemIds.includes(item.id)) {
      item.laneId = obj.id
      item.dataList.forEach((node) => {
        node.laneName = obj.laneName
        node.laneId = obj.id
      })
    }
  })
}
//区域编辑 要在库位编辑区域信息
const itemAreaManagementEdit = (obj) => {
  console.log(obj)
  state.allMapPointInfo.forEach((item) => {
    if (obj.mapItemIds.includes(item.id)) {
      item.areaId = obj.id
      item.dataList.forEach((node) => {
        node.areaName = obj.areaName
        node.skuInfo = obj.skuInfo
        node.areaId = obj.id
      })
    }
  })
}

//筛选图层
const layerSelectionSuccess = (typeList) => {
  state.allMapPointInfo.forEach((item) => {
    // 如果 type 存在于第一个数组中，则将 layerSelectionShow 设置为 false
    if (typeList.includes(item.type)) {
      item.layerSelectionShow = false
    } else {
      item.layerSelectionShow = true
    }
  })
}
//处理数据 考虑滚动条，缩放等各种情况的的坐标数据
const disposeEventPoints = (event) => {
  const rect = mapBackgroundRef.value.getBoundingClientRect()
  const scrollLeft = mapBackgroundRef.value.scrollLeft // 水平滚动条偏移量
  const scrollTop = mapBackgroundRef.value.scrollTop // 垂直滚动条偏移量
  // const devicePixelRatio = window.devicePixelRatio || 1 //浏览器缩放
  const devicePixelRatio = 1

  // 计算页面坐标（考虑设备像素比和滚动条偏移量）
  const x = (event.clientX - rect.left + scrollLeft) / state.imageChangeMultiple / devicePixelRatio
  const y = (event.clientY - rect.top + scrollTop) / state.imageChangeMultiple / devicePixelRatio

  // 转换为实际坐标
  const actualLocationX = imgBgObj.origin[0] + x * imgBgObj.resolution
  const actualLocationY = imgBgObj.origin[1] + (imgBgObj.height - y) * imgBgObj.resolution

  return {
    x,
    y,
    actualLocationX,
    actualLocationY
  }
}
//实际坐标 传入x y轴坐标
const disposeEventPoint = (x, y) => {
  const actualLocationX = Number(imgBgObj.origin[0]) + Number(x) * Number(imgBgObj.resolution)
  const actualLocationY =
    Number(imgBgObj.origin[1]) + (Number(imgBgObj.height) - Number(y)) * Number(imgBgObj.resolution)
  return {
    actualLocationX,
    actualLocationY
  }
}
// 传入实际现场的数据，转换成浏览器坐标的数据
const convertActualToBrowser = (pointX, pointY) => {
  const y1 = Number(imgBgObj.origin[1]) + Number(imgBgObj.height) * Number(imgBgObj.resolution)
  let x = Math.max(Number(pointX) - Number(imgBgObj.origin[0]), 0)
  let y = Math.max(y1 - Number(pointY), 0)

  return {
    x,
    y
  }
}
//将节点实际宽高cm转换成px
const cmConversionPx = (cWidth, cHeight) => {
  let pWidth = Number(cWidth) / imgBgObj.resolution / 100
  let pHeight = Number(cHeight) / imgBgObj.resolution / 100

  return {
    pWidth,
    pHeight
  }
}
// 计算直线中间箭头的路径
const getLineMidArrowPath = (item) => {
  const midX = (Number(item.startPointX) + Number(item.endPointX)) / 2
  const midY = (Number(item.startPointY) + Number(item.endPointY)) / 2

  let dx = item.endPointX - item.startPointX
  let dy = item.endPointY - item.startPointY
  let length = Math.sqrt(dx * dx + dy * dy)

  if (length === 0) {
    return `M ${midX} ${midY} L ${midX} ${midY}`
  }

  const unitDx = dx / length
  const unitDy = dy / length

  const arrowLength = 1
  const startXArrow = midX - unitDx * arrowLength
  const startYArrow = midY - unitDy * arrowLength
  const endXArrow = midX
  const endYArrow = midY

  return `M ${startXArrow} ${startYArrow} L ${endXArrow} ${endYArrow}`
}
// 计算贝塞尔曲线中间箭头的路径（简单近似）
const getBezierMidArrowPath = (item) => {
  const path = document.createElementNS('http://www.w3.org/2000/svg', 'path')
  path.setAttribute('d', item.curvePath)
  const length = path.getTotalLength()
  const midPoint = path.getPointAtLength(length / 2)
  const prevPoint = path.getPointAtLength(length / 2 - 1)
  return `M ${prevPoint.x} ${prevPoint.y} L ${midPoint.x} ${midPoint.y}`
}
// 计算贝塞尔曲线中间文字的 x 坐标
const computedCurveTextX = (item) => {
  return (
    (Number(item.startPointX) +
      Number(item.beginControlX) +
      Number(item.endControlX) +
      Number(item.endPointX)) /
    4
  )
}
// 计算贝塞尔曲线中间文字的 y 坐标
const computedCurveTextY = (item) => {
  return (
    (Number(item.startPointY) +
      Number(item.beginControlY) +
      Number(item.endControlY) +
      Number(item.endPointY)) /
    4
  )
}
document.onmousedown = function (e) {
  //右击
  if (e.button == 2) {
    state.selectedCurve = ''
    //清除路线的选中
    state.mapRouteList.forEach((item) => {
      item.isSelected = false
    })
    state.currentDragTarget = { index: null, type: null }
    state.currentItemIndex = -1
  }
}
// 阻止默认菜单弹出
window.document.oncontextmenu = function () {
  return false
}
//监听键盘事件
const handleKeyDown = (event) => {
  if (event.ctrlKey) {
    if (event.key === 'c') {
      //复制
      if (state.currentItemIndex === -1) {
        message.warning('请先选择要操作的对象')
        return
      }
      replicationNode()
    } else if (event.key === 'v') {
      //粘贴
      if (!state.copyMapItem) {
        message.warning('请先复制对象')
        return
      }
      pasteNode()
    } else if (event.key === 'z') {
      //撤回
      backPreviousStep()
    } else if (event.key === 'y') {
      //重写
      backNextStep()
    }
  }
}

//鼠标滚轮
const handleWheel = (event) => {
  // 判断 Ctrl 键是否被按下
  if (event.ctrlKey) {
    // 阻止默认的滚动行为
    event.preventDefault()

    // 根据滚轮滚动方向调整缩放比例
    if (event.deltaY < 0) {
      // 向上滚动，放大
      //放大
      if (state.imageChangeMultiple < 4) {
        state.imageChangeMultiple += 0.2
      } else {
        state.imageChangeMultiple = 3.8
        message.warning('不能在放大了')
      }
    } else {
      //缩小
      if (state.imageChangeMultiple > 0.2) {
        state.imageChangeMultiple -= 0.1
      } else {
        state.imageChangeMultiple = 0.1
        message.warning('不能在缩小了')
      }
    }
  }
}

const addEventListener = () => {
  window.addEventListener('keydown', handleKeyDown)
}
const removeEventListener = () => {
  window.removeEventListener('keydown', handleKeyDown)
}

const router = useRouter()
onBeforeRouteLeave((to, from) => {
  if (to.path == '/mapPage/realTimeMap' && to.query.mapId != imgBgObj.positionMapId) {
    router.replace({
      name: 'MapPageRealTimeMap',
      query: {
        mapId: imgBgObj.positionMapId
      }
    })
  }
})

onMounted(() => {
  getMapList()
  window.addEventListener('keydown', handleKeyDown)
})

onUnmounted(() => {
  window.removeEventListener('keydown', handleKeyDown)
})
</script>

<style lang="scss" scoped>
.item-tooltip-name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 200px;
}

.edit-map-page {
  .map-container {
    position: relative;
    width: 100%;
    overflow: auto;
    // height: 85vh;
    height: calc(100vh - 140px);

    .map-bg {
      background-size: contain;
      background-repeat: no-repeat;
      position: absolute;
      // top: 18px;
      // left: 18px;
      top: 0;
      left: 0;

      .map-box-inner {
        position: absolute;
        top: 0;
        left: 0;
      }
    }
  }

  .top-tool {
    margin-bottom: 2px;
    .top-tool-list {
      display: flex;
      align-items: center;
      text-align: center;
      background-color: #fff;
      padding: 0 12px;
      height: 70px;
      box-shadow: rgba(0, 0, 0, 0.06) 0px 2px 3px;

      .top-tool-item {
        display: flex;
        align-items: center;

        .tool-item {
          cursor: pointer;
          width: 50px;
          height: 70px;
          display: flex;
          flex-direction: column;
          align-items: center;
          justify-content: center;

          .name {
            cursor: pointer;
            font-family:
              PingFangSC,
              PingFang SC;
            font-weight: 400;
            font-size: 14px;
            color: #0d162a;
            line-height: 20px;
            text-align: center;
            font-style: normal;
            margin-top: 4px;
          }
        }
        .line {
          margin: 0 12px;
          width: 1px;
          height: 47px;
          border: 1px solid #cccccc;
        }
      }
    }

    .right-tool-list {
      position: absolute;
      right: 0;
      top: 114px;
      background-color: #fff;
      z-index: 999;
      text-align: center;
      box-shadow: rgba(0, 0, 0, 0.05) 0px 0px 0px 1px;

      .tool-item {
        cursor: pointer;
        padding: 10px;
        .name {
          font-family:
            PingFangSC,
            PingFang SC;
          font-weight: 400;
          font-size: 14px;
          color: #0d162a;
          line-height: 20px;
          text-align: center;
          font-style: normal;
        }
      }
    }
  }

  .input-box-class {
    position: absolute;
    border: 1px solid #00329f;
    padding: 4px;
    outline: none;
  }

  .selection-area-btn {
    width: 80px;
    margin-left: 4px;
  }

  .grid-show {
    // background: linear-gradient(-90deg, rgba(0, 0, 0, 0.1) 1px, transparent 1px),
    //   linear-gradient(rgba(0, 0, 0, 0.1) 1px, transparent 1px);
    // background-size:
    //   20px 20px,
    //   20px 20px;

    background-image: repeating-linear-gradient(
        to right,
        rgba(0, 0, 0, 0.1),
        rgba(0, 0, 0, 0.1) 1px,
        transparent 1px,
        transparent 50px
      ),
      repeating-linear-gradient(
        to bottom,
        rgba(0, 0, 0, 0.1),
        rgba(0, 0, 0, 0.1) 1px,
        transparent 1px,
        transparent 50px
      );
  }

  .svg-div {
    z-index: 99999;

    svg {
      cursor: crosshair;

      path.selected {
        stroke: blue;
      }
    }
  }

  .node-text {
    white-space: nowrap; /* 防止文字自动换行 */
  }
}

.tool-active {
  background: #ebf1ff;
  border-bottom: 2px solid #1677ff;
}

.right-tool-active {
  background: #ebf1ff !important;
}

.drop-down-menu {
  .drop-down-menu-item {
    cursor: pointer;
    display: flex;
    flex-direction: column;
    align-items: center;
    width: 100%;
    padding: 11px 0;
    font-family:
      PingFangSC,
      PingFang SC;
    font-weight: 400;
    font-size: 14px;
    color: #0d162a;
    line-height: 20px;
    text-align: left;
    font-style: normal;
    border-bottom: 1px solid #e9e9e9;
  }
}

.sort-num {
  position: absolute;
  font-size: 12px;
  user-select: none;
  color: #000;
}
.sort-num-location {
  position: absolute;
  font-size: 12px;
  user-select: none;
  color: #000;
}
.actual-location {
  position: fixed;
  bottom: 10px;
  right: 16px;
  background-color: #f48924;
  color: #fff;
  padding: 6px;
  border-radius: 2px;
  font-size: 14px;
  user-select: none;
}
</style>
