<template>
  <div class="map-container" v-loading="loadingPage">
    <div class="mapLeft">
      <div class="mapbox">
        <div v-if="activeFloorData.img" ref="mapContainer" class="map"></div>
        <div v-else class="upload">
          <div class="upBox">
            <div style="display: flex; overflow: hidden; width: 100%; height: 100%; opacity: 0">
              <MOSTY.Upload
                :width="'100%'"
                :height="'100%'"
                :disabled="props.type == 'view' || props.type == 'approve'"
                :limit="1"
                :nopicer="false"
                :isImg="true"
                :ShowfileList="false"
                v-model="activeFloorData.img"
                :nameshow="false"
                :gsgfList="['jpg', 'png']"
                @filehandleChange="changeFile"
              >
              </MOSTY.Upload>
            </div>
          </div>
        </div>
      </div>
      <div class="floorBox">
        <div
          class="floor_item"
          v-for="(e, i) in floorBox"
          :key="e"
          @click="checkFloor(i)"
          :class="{ active: activeFloor == i }"
        >
          {{ e.name }}
        </div>
      </div>
    </div>
    <div class="sidebar">
      <div class="sidebar_item">
        <div class="sidebar_item_head"><span>设备统计</span></div>
        <div class="sbtj">
          <div class="sbtj_item">
            <div class="sbtj_item_name">设备总数</div>
            <div class="sbtj_item_data">{{ isUseIcon.all }}</div>
          </div>
          <div class="sbtj_item">
            <div class="sbtj_item_name">已上图数量</div>
            <div class="sbtj_item_data">{{ isUseIcon.used }}</div>
          </div>
        </div>
      </div>
      <div class="sidebar_item">
        <div class="sidebar_item_head"><span>设备配置</span></div>
        <template v-for="(marker, index) in markerOptions" :key="marker.key">
          <div class="sbbox_s" v-if="marker.data && marker.data.length > 0">
            <div class="sbbox_tit">{{ marker.name }}</div>
            <div class="sbbox">
              <template v-for="(marker2, index) in marker.data" :key="marker2">
                <div class="sbbox_item" draggable="true" @dragstart="startDragFromSidebar($event, marker2)">
                  <img :src="getIcon(marker2.zsblx)" :alt="marker.name" class="marker-icon" />
                  <div>{{ marker2.name }}</div>
                </div>
              </template>
            </div>
          </div>
        </template>
      </div>
    </div>
    <div
      ref="popup"
      class="my-popup"
      v-show="popupVisible"
      :style="{ left: popupData.popupLeft + 'px', top: popupData.popupTop + 'px' }"
    >
      <div class="closep" @click.stop="closePopup"></div>
      <div class="popup-content">
        <h3>{{ popupData.title }}</h3>
        <div class="contentBox">
          <p>设备名称：{{ popupData.content?.sbmc }}</p>
          <p>设备位置：{{ popupData.content?.sbwz }}</p>
          <p>设备ID：{{ popupData.content?.sbid }}</p>
          <p>设备IP：{{ popupData.content?.sbip }}</p>
          <p>设备厂商：{{ popupData.content?.sbcs }}</p>
          <p>所属部门：{{ popupData.content?.ssbm }}</p>
          <p>责任人{{ popupData.content?.zrr }}</p>
        </div>
      </div>
    </div>
  </div>
</template>
<script setup>
import { ref, onMounted, watch, computed } from "vue"
import { ElMessage } from "element-plus"
import Map from "ol/Map"
import View from "ol/View"
import { Image as ImageLayer } from "ol/layer"
import { ImageStatic } from "ol/source"
import Overlay from "ol/Overlay"
import { Vector as VectorLayer } from "ol/layer"
import { Vector as VectorSource } from "ol/source"
import Feature from "ol/Feature"
import Point from "ol/geom/Point"
import { Icon, Style } from "ol/style"
import { Modify, Select } from "ol/interaction"
import { doubleClick } from "ol/events/condition"
import { platformModifierKeyOnly } from "ol/events/condition"
import { pointerMove, click } from "ol/events/condition"
import * as MOSTY from "@/components/MyComponents/index"
import { getApi } from "@/api/tobAcco_api.js"
import {
  selectPmtFloorConf,
  savePmtFloor,
  saveBjsssbConf,
  listBjsssbConf,
  deletePmtFloor,
  deleteBjsssbConf,
  listAttaInfo,
  getAttaBasicInfo
} from "@/api/sbpz"
const loadingPage = ref(false)
const floorBox = ref([
  {
    name: "",
    value: 1,
    img: ""
  }
])
const activeFloor = ref(0)
const activeFloorData = ref(floorBox.value[activeFloor.value])
const props = defineProps({
  obj: {
    type: Object,
    default: {}
  }
})
watch(
  () => props.obj,
  newVal => {
    console.log("Received in child:", newVal)
  }
)
const actionUrl = computed(() => "/mosty-api/mosty-base/minio/image/upload/id")
const formData = ref({
  titleFile: null
})
const changeFile = () => {
  let s = activeFloorData.value.img
  activeFloorData.value.picid = s[0]
  getApi({}, `/mosty-base/minio/file/download/${s}`).then(res => {
    activeFloorData.value.img = floorBox.value[activeFloor.value].img = res.url
    let imageWidth = 2000
    let imageHeight = 1500
    let img = new Image()
    img.src = res.url
    img.onload = function () {
      imageWidth = this.width
      imageHeight = this.height
      console.log("图片宽度：" + imageWidth)
      console.log("图片高度：" + imageHeight)
    }
    activeFloorData.value.pmtcd = imageWidth
    activeFloorData.value.pmtgd = imageHeight
    postSavePmtFloor(1)
  })
}
const checkFloor = index => {
  console.log("当前楼层", index)
  activeFloor.value = index
  activeFloorData.value = floorBox.value[index]
  if (floorBox.value[index].img) {
    setTimeout(() => {
      initMap()
    }, 50)
  }
}
const popupVisible = ref(false)
const popupData = ref({ popupLeft: "", popupTop: "", title: "", content: "" })
const closePopup = e => {
  popupVisible.value = !popupVisible.value
}
const mapContainer = ref(null)
const map = ref(null)
const markerSource = ref(new VectorSource())
const selectedMarker = ref(null)
const selectInteraction = ref(null)
const modifyInteraction = ref(null)
const currentDragMarker = ref(null)
const markerOptions = ref([])
const handleImageLoadEnd = () => {
  console.log("图片加载完成")
  loadingPage.value = false
}
const handleImageLoadError = () => {
  console.log("图片加载失败")
  loadingPage.value = false
  ElMessage.error("楼层图加载失败，请检查网络是否正常!")
}
const initMap = () => {
  loadingPage.value = true
  map.value = null
  let url = activeFloorData.value.img
  let imageWidth = activeFloorData.value.pmtcd
  let imageHeight = activeFloorData.value.pmtgd
  const imageSource = new ImageStatic({
    url: url,
    imageExtent: [0, 0, imageWidth, imageHeight],
    projection: "EPSG:3857"
  })
  const imageLayer = new ImageLayer({
    source: imageSource,
    zIndex: 0
  })
  imageSource.on("imageloadend", handleImageLoadEnd)
  imageSource.on("imageloaderror", handleImageLoadError)
  const vectorLayer = new VectorLayer({
    source: markerSource.value,
    style: new Style({
      image: new Icon({
        src: "https://maps.google.com/mapfiles/ms/micons/red.png",
        scale: 1
      })
    }),
    zIndex: 10
  })
  map.value = new Map({
    target: mapContainer.value,
    layers: [imageLayer, vectorLayer],
    view: new View({
      center: [imageWidth / 2, imageHeight / 2],
      zoom: 1,
      extent: [0, 0, imageWidth, imageHeight],
      projection: "EPSG:3857"
    })
  })
  map.value.on("click", event => {
    selectFeature(event)
  })
  const modifyInteraction = new Modify({
    source: markerSource.value
  })
  map.value.addInteraction(modifyInteraction)
  modifyInteraction.on("modifystart", event => {
    if (event.features.getLength() > 0) {
    }
  })
  modifyInteraction.on("modifyend", event => {
    if (event.features.getLength() > 0) {
      const feature = event.features.item(0)
      const markerData = feature.get("markerData")
      const newCoordinates = feature.getGeometry().getCoordinates()
      if (
        newCoordinates[0] < 0 ||
        newCoordinates[1] < 0 ||
        newCoordinates[0] > activeFloorData.value.pmtcd ||
        newCoordinates[1] > activeFloorData.value.pmtgd
      ) {
        console.log("超出，删除")
        markerSource.value.removeFeature(feature)
        switch (markerData.pname) {
          case "XFSB":
            markerOptions.value[1].data.push(markerData)
            break
          case "SPJK":
            markerOptions.value[0].data.push(markerData)
            break
          case "QT":
            markerOptions.value[2].data.push(markerData)
            break
          default:
        }
        delBJD(markerData)
      } else {
        saveMaker(newCoordinates, markerData, 1)
      }
    }
  })
  map.value.getView().fit([0, 0, imageWidth, imageHeight], {
    padding: [20, 20, 20, 320]
  })
  setupMapInteractions()
  setupDropEvents()
}
const setupMapInteractions = () => {
  if (selectInteraction.value) map.value.removeInteraction(selectInteraction.value)
  if (modifyInteraction.value) {
    map.value.removeInteraction(modifyInteraction.value)
  }
  selectInteraction.value = new Select({
    condition: click,
    layers: [map.value.getLayers().getArray()[1]],
    style: new Style({
      image: new Icon({
        src: "https://maps.google.com/mapfiles/ms/micons/yellow.png",
        scale: 1.2
      })
    })
  })
  modifyInteraction.value = new Modify({
    features: selectInteraction.value.getFeatures()
  })
  map.value.addInteraction(selectInteraction.value)
  map.value.addInteraction(modifyInteraction.value)
  modifyInteraction.value.on("modifyend", event => {})
  selectInteraction.value.on("select", e => {
    selectedMarker.value = e.selected[0] || null
  })
}
const selectedFeature = ref(null)
const selectFeature = event => {
  map.value.forEachFeatureAtPixel(event.pixel, feature => {
    const geometry = feature.getGeometry()
    const coordinate = geometry.getCoordinates()
    selectedFeature.value = {
      id: feature.get("id"),
      coordinate: [Math.round(coordinate[0] * 100) / 100, Math.round(coordinate[1] * 100) / 100],
      markerData: feature.get("markerData")
    }
    popupData.value.popupLeft = event.pixel[0] + 10
    popupData.value.popupTop = event.pixel[1] - 330
    getSbInfo()
    return true
  })
}
const getSbInfo = async () => {
  const res = await getAttaBasicInfo({
    zsblx: selectedFeature.value.markerData.zsblx,
    sbid: selectedFeature.value.markerData.sbid,
    zsbid: selectedFeature.value.markerData.zsbid,
    name: selectedFeature.value.markerData.name
  })
  popupData.value.title = selectedFeature.value.markerData.name
  popupData.value.content = res
  console.log(popupData.value)
  popupVisible.value = true
}
const setupDropEvents = () => {
  const mapElement = mapContainer.value
  mapElement.addEventListener("dragover", e => {
    e.preventDefault()
  })
  mapElement.addEventListener("drop", e => {
    e.preventDefault()
    if (!currentDragMarker.value) return
    const pixel = [
      e.clientX - mapElement.getBoundingClientRect().left,
      e.clientY - mapElement.getBoundingClientRect().top
    ]
    const coordinate = map.value.getCoordinateFromPixel(pixel)
    if (!coordinate) return
    markerOptions.value.map((e, i1) => {
      e.data.map((j, i2) => {
        if (j.sbid == currentDragMarker.value.sbid) {
          markerOptions.value[i1].data.splice(i2, 1)
        }
      })
    })
    addNewMarker(coordinate, currentDragMarker.value)
    saveMaker(coordinate, currentDragMarker.value)
    currentDragMarker.value = null
  })
}
const getIcon = name => {
  let url = ""
  switch (name) {
    case "SPJK":
    case "XFSB":
    case "TCC":
    case "DQHZ":
      url = `../mapicon/icon/${name}.png`
      break
    default:
      url = `../mapicon/icon/QT.png`
  }
  return url
}
const addNewMarker = (coordinate, markerData) => {
  const markerId = `marker_${Date.now()}`
  const marker = new Feature({
    geometry: new Point(coordinate),
    id: markerId,
    markerData: markerData,
    name: markerData.name
  })
  marker.setStyle(
    new Style({
      image: new Icon({
        src: getIcon(markerData.zsblx),
        scale: 1,
        anchor: [0.5, 1]
      })
    })
  )
  markerSource.value.addFeature(marker)
  setTimeout(() => {}, 50)
}
const startDragFromSidebar = (event, marker) => {
  currentDragMarker.value = marker
  event.dataTransfer.setData("text/plain", marker.name)
  const dragImage = new Image()
  dragImage.src = getIcon(marker.zsblx)
  event.dataTransfer.setDragImage(dragImage, 16, 32)
}
const removeSelectedMarker = () => {
  if (selectedMarker.value) {
    markerSource.value.removeFeature(selectedMarker.value)
    selectedMarker.value = null
  }
}
const formatCoordinates = coord => {
  return coord ? `X: ${coord[0].toFixed(2)}, Y: ${coord[1].toFixed(2)}` : ""
}
const PmtFloorConfdata = ref({})
const getselectPmtFloorConf = async () => {
  props.obj["img"] = ""
  floorBox.value[0] = props.obj
  const params = {
    floorid: props.obj.floorid,
    buildingid: props.obj.buildingid,
    placeid: props.obj.siteid
  }
  const res = await selectPmtFloorConf(params)
  PmtFloorConfdata.value = res || {}
  activeFloorData.value = res || {}
  if (res.pmtFileid) {
    getApi({}, `/mosty-base/minio/file/download/${res.pmtFileid}`).then(res2 => {
      activeFloorData.value.img = PmtFloorConfdata.value.img = res2.url || ""
      setTimeout(() => {
        initMap()
      }, 500)
    })
  }
}
const isUseIcon = ref({
  all: 0,
  used: 0
})
const getlistAttaInfo = async () => {
  const params = {
    floorid: props.obj.floorid,
    buildingid: props.obj.buildingid,
    placeid: props.obj.siteid
  }
  const res = await listAttaInfo(params)
  for (const item in res) {
    isUseIcon.value.all += res[item].length
    let s = {}
    res[item].map(k => (k.pname = item))
    switch (item) {
      case "XFSB":
        s = {
          name: "消防设备",
          key: item,
          data: res[item]
        }
        markerOptions.value[1] = s
        break
      case "SPJK":
        s = {
          name: "视频监控",
          key: item,
          data: res[item]
        }
        markerOptions.value[0] = s
        break
      case "QT":
        s = {
          name: "其他",
          key: item,
          data: res[item]
        }
        markerOptions.value[2] = s
        break
      default:
    }
  }
}
const getlistBjsssbConf = async () => {
  const params = {
    pmtid: activeFloorData.value.pmtFileid
  }
  const res = await listBjsssbConf(params)
  isUseIcon.value.used = res.length
  markerOptions.value.map((e, i1) => {
    e.data.map((j, i2) => {
      res.map((i, index) => {
        if (j.sbid == i.sbid && j.zsblx == i.zsblx) {
          markerOptions.value[i1].data.splice(i2, 1)
          j.piontId = i.id
          addNewMarker([res[index].x, res[index].y], j)
        }
      })
    })
  })
}
const postSavePmtFloor = async () => {
  const params = {
    id: PmtFloorConfdata.value.id,
    pmtFileid: activeFloorData.value.picid,
    pmtcd: activeFloorData.value.pmtcd,
    pmtgd: activeFloorData.value.pmtgd,
    floorid: props.obj.floorid,
    buildingid: props.obj.buildingid,
    placeid: props.obj.siteid
  }
  const res = await savePmtFloor(params)
  setTimeout(() => {
    initMap()
  }, 500)
}
const saveMaker = async (coordinate, markerData, type) => {
  const params = {
    pmtid: activeFloorData.value.pmtFileid,
    sbid: markerData.sbid,
    zsbid: markerData.zsbid,
    zsblx: markerData.zsblx,
    x: coordinate[0],
    y: coordinate[1]
  }
  if (type == 1) {
    params.id = markerData.piontId
  } else {
    isUseIcon.value.used += 1
  }
  const res = await saveBjsssbConf(params)
}
const wdeletePmtFloor = async () => {
  const params = {
    floorid: props.obj.floorid,
    buildingid: props.obj.buildingid,
    placeid: props.obj.siteid
  }
  const res = await deletePmtFloor(params)
}
const delBJD = async markerData => {
  const res2 = await deleteBjsssbConf({ sbid: markerData.sbid, zsbid: markerData.zsbid })
  isUseIcon.value.used -= 1
}
onMounted(() => {
  setTimeout(async () => {
    await getselectPmtFloorConf()
    await getlistAttaInfo()
    await getlistBjsssbConf()
  }, 50)
})
</script>
<style scoped lang="scss">
$gold-colors: linear-gradient(90deg, #dbf9ff 0%, #a9f0ff 100%);
.map-container {
  display: flex;
  height: 100vh;
  height: calc(100% - 0px);
  background: url("~@/assets/sbpz/Rectangle_bg.png") no-repeat;
  background-size: 100% 100%;
  position: relative;
  .mapLeft {
    height: calc(100vh - 150px);
    margin: 10px;
    padding: 3px;
    flex: 1;
    background: url("~@/assets/sbpz/Rectangle.png") no-repeat;
    background-size: 100% 100%;
    .mapbox {
      height: 100%;
      height: calc(100% - 60px);
      .map {
        width: 100%;
        height: 100%;
      }
      .upload {
        width: 100%;
        height: 100%;
        display: flex;
        align-items: center;
        justify-content: center;
        .upBox {
          width: 264px;
          height: 172px;
          background: url("~@/assets/sbpz/Group 427322413.png") no-repeat;
          background-size: 100% 100%;
          cursor: pointer;
          overflow: hidden;
          :deep(.form-item-box) {
            width: 100% !important;
            height: 100% !important;
          }
        }
      }
    }
    .floorBox {
      height: 60px;
      display: flex;
      justify-content: center;
      align-items: center;
      .floor_item {
        width: 100px;
        height: 32px;
        display: flex;
        align-items: center;
        justify-content: center;
        color: #e7faff;
        cursor: pointer;
        background: url("~@/assets/sbpz/Rectangle_btn2.png") no-repeat;
        background-size: 100% 100%;
        margin: 0 15px;
        &.active {
          background: url("~@/assets/sbpz/Rectangle_btn.png") no-repeat;
          background-size: 100% 100%;
        }
      }
    }
  }
  .sidebar {
    width: 426px;
    padding: 15px;
    border-right: 1px solid #ddd;
    overflow-y: auto;
    .sidebar_item {
      .sidebar_item_head {
        height: 35px;
        width: 398px;
        background: url("~@/assets/sbpz/Rectangle_top_a.png") no-repeat;
        background-size: 100% 100%;
        display: flex;
        align-items: center;
        padding-left: 60px;
        span {
          font-size: 16px;
          display: inline-block;
          background: $gold-colors;
          background-clip: text;
          color: transparent;
        }
      }
      .sbtj {
        width: 296px;
        height: 93px;
        background: url("~@/assets/sbpz/Frame 48.png") no-repeat;
        background-size: 100% 100%;
        margin: 20px auto;
        display: flex;
        align-items: center;
        padding-left: 80px;
        padding-left: 70px;
        .sbtj_item {
          padding-left: 26px;
          text-align: center;
          .sbtj_item_name {
            font-size: 14px;
            color: #cbf2fa;
          }
          .sbtj_item_data {
            color: #27ddf1;
            font-weight: bold;
            font-size: 18px;
            margin-top: 10px;
          }
        }
      }
      .sbbox_s {
        .sbbox_tit {
          width: 300px;
          height: 26px;
          text-align: center;
          margin: 20px auto;
          line-height: 26px;
          color: #c4f3fe;
          background: url("~@/assets/sbpz/Rectangle_tit.png") no-repeat;
          background-size: 100% 100%;
        }
        .sbbox {
          display: flex;
          flex-wrap: wrap;
          .sbbox_item {
            margin: 10px 0;
            width: 33%;
            display: flex;
            flex-direction: column;
            justify-content: center;
            align-items: center;
            gap: 10px;
            color: #bedef3;
          }
        }
      }
    }
    .marker-options {
      display: flex;
      gap: 10px;
      margin-bottom: 20px;
      width: 286px;
      height: 93px;
      background: linear-gradient(
        270deg,
        rgba(203, 242, 250, 0) 0%,
        rgba(203, 242, 250, 0.22) 48%,
        rgba(203, 242, 250, 0) 100%
      );
      border-radius: 5px 5px 5px 5px;
      border: 1px solid;
      border-image: linear-gradient(156deg, rgba(33, 202, 236, 0), rgba(11, 143, 170, 0), rgba(72, 222, 252, 1)) 1 1;
      .marker-item {
        width: 33%;
        display: flex;
        align-items: center;
        justify-content: center;
        flex-direction: column;
        padding: 8px;
        background: white;
        border: 1px solid #ddd;
        border-radius: 4px;
        cursor: grab;
        color: #000;
        div {
          color: #000;
        }
        .marker-icon {
          width: 24px;
          height: 24px;
          margin-right: 8px;
        }
        &:hover {
          background: #f0f0f0;
        }
      }
    }
  }
}
.selected-marker-info {
  margin-top: 20px;
  padding: 15px;
  background: white;
  border: 1px solid #ddd;
  border-radius: 4px;
}
.selected-marker-info h4 {
  margin-top: 0;
  color: #333;
}
.selected-marker-info button {
  margin-top: 10px;
  padding: 5px 10px;
  background: #ff4444;
  color: white;
  border: none;
  border-radius: 3px;
  cursor: pointer;
}
.selected-marker-info button:hover {
  background: #cc0000;
}
.my-popup {
  position: absolute;
  border: 0px solid #cccccc;
  width: 450px;
  height: 306px;
  z-index: 1000;
  background: url("~@/assets/sbpz/Group 427322382.png") no-repeat;
  background-size: 100% 100%;
  .closep {
    position: absolute;
    width: 31px;
    height: 31px;
    right: 0;
    top: 0;
    cursor: pointer;
  }
  .popup-content {
    padding: 28px;
    h3 {
      margin-top: 16px;
      height: 40px;
      line-height: 40px;
      text-align: center;
    }
    p {
      margin: 10px 0;
    }
  }
}
</style>
