<!--
 * @Author: SunTao 328867980@qq.com
 * @Date: 2024-10-14 13:59:51
 * @LastEditors: SunTao 328867980@qq.com
 * @LastEditTime: 2025-01-07 15:53:44
 * @FilePath: \znxjxt-ui\src\views\xj\inspection\surface-management\index.vue
 * @Description: 巡检管理-路面病害对比
-->

<template>
  <div class="surface-content">
    <div class="surface-form">
      <el-form
        :model="surfaceForm"
        ref="surfaceForm"
        size="small"
        :inline="true"
        :rules="rules"
        label-width="7rem"
      >
        <el-form-item label="路段名称" prop="segmentId">
          <el-select
            ref="segmentIdSelect"
            v-model="surfaceForm.segmentId"
            placeholder="请选择道路名称"
            clearable
            filterable
          >
            <el-option
              v-for="item in segmentList"
              :key="item.value"
              :label="item.label"
              :value="item.value"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="时间" prop="time">
          <el-date-picker
            v-model="surfaceForm.time"
            type="date"
            value-format="yyyy-MM-dd"
            placeholder="选择日期"
          >
          </el-date-picker>
        </el-form-item>
        <el-form-item label="病害类型">
          <el-cascader
            ref="segmentIdCascader"
            v-model="surfaceForm.defectType"
            :options="defectTypeList"
            :props="{
              checkStrictly: false,
              emitPath: false,
              children: 'subTypes',
            }"
            clearable
          ></el-cascader>
        </el-form-item>
        <el-form-item label="">
          <el-button
            type="primary"
            icon="el-icon-search"
            size="mini"
            @click="handleQuery"
            >确定</el-button
          >
        </el-form-item>
      </el-form>
    </div>
    <div class="surface-map">
      <div class="surface-div">
        <surface-map
          ref="surfaceLeft"
          :id="'0'"
          @clearMap="clearLeftMap"
          @send-img="sendLeftImg"
          :mapLogeList="mapLogeList"
          :mapObject="surfaceListLeft"
        ></surface-map>
      </div>
      <div class="surface-div">
        <surface-map
          ref="surfaceRight"
          :id="'1'"
          @clearMap="clearRightMap"
          @send-img="sendRightImg"
          :mapLogeList="mapLogeList"
          :mapObject="surfaceListRight"
        ></surface-map>
      </div>
    </div>
    <!-- 点位查看图片弹窗 -->
    <el-dialog
      title="病害对比查看"
      :visible.sync="viewVisible"
      width="90rem"
      append-to-body
      :close-on-click-modal="false"
      destroy-on-close
      @close="viewCancel"
    >
      <div class="dialog-div">
        <div class="img-div" ref="imageLeft">
          <img
            :src="dialogImgLeft.imageUrl"
            @load="updateLeftRects"
            alt="Main Image"
            ref="mainImageLeft"
          />
          <div
            v-for="(rect, index) in rectsLeft"
            :key="`left-${index}`"
            class="rect-overlay"
            :style="getRectStyleLeft(rect)"
          ></div>
        </div>
        <div class="img-div" ref="imageRight">
          <img
            :src="dialogImgRight.imageUrl"
            @load="updateRightRects"
            alt="Main Image"
            ref="mainImageRight"
          />
          <div
            v-for="(rect, index) in rectsRight"
            :key="`right-${index}`"
            class="rect-overlay"
            :style="getRectStyleRight(rect)"
          ></div>
        </div>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import {
  getSegment,
  getDefectList,
  getDefectSelectList,
  getCompareList,
} from "@/api/xj/surface";
import SurfaceMap from "./components/surface-map.vue";
export default {
  name: "Surface",
  components: { SurfaceMap },
  data() {
    return {
      // 搜索表单
      surfaceForm: {
        // 路段名称
        segmentId: "",
        // 时间
        time: "",
        // 病害类型
        defectType: "",
      },
      // 道路名称下拉数据
      segmentList: [],
      // 病害类型下拉数据
      defectTypeList: [],
      // 地图图标map
      mapLogeList: {},
      // 获取到的查询结果-左侧
      surfaceListLeft: {},
      // 获取到的查询结果-右侧
      surfaceListRight: {},
      // 左侧弹窗图片数据
      dialogImgLeft: {},
      // 左侧弹窗红框数据
      rectsLeft: [],
      // 右侧弹窗图片数据
      dialogImgRight: "",
      // 右侧弹窗红框数据
      rectsRight: [],
      // 表单验证
      rules: {
        segmentId: [
          { required: true, message: "请选择路段", trigger: "change" },
        ],
        time: [{ required: true, message: "请选择时间", trigger: "change" }],
      },
      // 病害对比弹窗显隐控制
      viewVisible: false,
    };
  },
  created() {
    this.getSegmentList();
    this.getDefectTypeList();
    this.getDefectTypeSelect();
  },
  mounted() {},
  methods: {
    /* 获取路段下拉数据 */
    getSegmentList() {
      getSegment().then(({ code, data }) => {
        if (code === 200) {
          this.segmentList = data;
        }
      });
    },

    /* 获取病害类型级联下拉数据 */
    getDefectTypeList() {
      getDefectList().then(({ code, data }) => {
        if (code === 200) {
          this.defectTypeList = data;
        }
      });
    },

    /* 获取病害类型下拉数据 */
    getDefectTypeSelect() {
      getDefectSelectList().then(({ code, data }) => {
        if (code === 200) {
          data.forEach((item) => {
            this.mapLogeList[item.value] = item.label;
          });
        }
      });
    },

    /* 点击确定事件 */
    handleQuery() {
      this.$refs["surfaceForm"].validate((valid) => {
        if (valid) {
          if (
            Object.keys(this.surfaceListLeft).length > 0 &&
            Object.keys(this.surfaceListRight).length > 0
          ) {
            this.$modal.msgWarning("请删除一个图层后再进行路面病害对比");
          } else {
            getCompareList(this.surfaceForm).then(({ code, data }) => {
              if (code === 200) {
                if (
                  Object.keys(this.surfaceListLeft).length < 1 &&
                  data.data.length > 0
                ) {
                  const [node] = this.$refs.segmentIdCascader.getCheckedNodes();
                  this.surfaceListLeft = {
                    ...data,
                    title: `${this.$refs.segmentIdSelect.selected.label}——${
                      this.surfaceForm.time
                    }——${node?.label || "全部病害"}`,
                  };
                } else if (
                  Object.keys(this.surfaceListRight).length < 1 &&
                  data.data.length > 0
                ) {
                  const [node] = this.$refs.segmentIdCascader.getCheckedNodes();
                  this.surfaceListRight = {
                    ...data,
                    title: `${this.$refs.segmentIdSelect.selected.label}——${
                      this.surfaceForm.time
                    }——${node?.label || "全部病害"}`,
                  };
                }
              }
            });
          }
        }
      });
    },

    /* 删除左侧图层 */
    clearLeftMap() {
      this.surfaceListLeft = {};
      this.dialogImgLeft = {};
    },

    /* 删除右侧图层 */
    clearRightMap() {
      this.surfaceListRight = {};
      this.dialogImgRight = {};
    },

    /* 点击左侧点位传回来的图片 */
    sendLeftImg(item) {
      this.dialogImgLeft = item.data;
      if (Object.keys(this.surfaceListRight).length > 0) {
        const rightImg = this.surfaceListRight.data.filter((it) => {
          return it.snapshotId === item.data.snapshotId && it;
        });
        this.dialogImgRight = rightImg[0];
      }
      this.viewVisible = true;
    },

    /* 点击右侧点位传回来的图片 */
    sendRightImg(item) {
      this.dialogImgRight = item.data;
      if (Object.keys(this.surfaceListLeft).length > 0) {
        const leftImg = this.surfaceListLeft.data.filter((it) => {
          return it.snapshotId === item.data.snapshotId && it;
        });
        this.dialogImgLeft = leftImg[0];
      }
      this.viewVisible = true;
    },

    /* 更新左侧红框位置 */
    updateLeftRects() {
      const rects = this.dialogImgLeft?.rect?.split(",").map(Number) || [];
      this.rectsLeft = [
        {
          left: rects[0],
          top: rects[1],
          width: rects[2],
          height: rects[3],
        },
      ];
    },

    /* 更新右侧红框位置 */
    updateRightRects() {
      const rects = this.dialogImgRight?.rect?.split(",").map(Number) || [];
      this.rectsRight = [
        {
          left: rects[0],
          top: rects[1],
          width: rects[2],
          height: rects[3],
        },
      ];
    },

    /* 左侧红框样式 */
    getRectStyleLeft({ left, top, width, height }) {
      const image = this.$refs.mainImageLeft;
      const container = this.$refs.imageLeft;
      if (!image || !container) return {};

      const scaleX = container.clientWidth / image.naturalWidth;
      const scaleY = container.clientHeight / image.naturalHeight;
      const scale = Math.min(scaleX, scaleY);

      const renderedWidth = image.naturalWidth * scale;
      const renderedHeight = image.naturalHeight * scale;

      const offsetX = (container.clientWidth - renderedWidth) / 2;
      const offsetY = (container.clientHeight - renderedHeight) / 2;

      return {
        position: "absolute",
        left: `${left * scale + offsetX}px`,
        top: `${top * scale + offsetY}px`,
        width: `${width * scale}px`,
        height: `${height * scale}px`,
        border: "2px solid #FF0000",
        boxSizing: "border-box",
      };
    },

    /* 右侧红框样式 */
    getRectStyleRight({ left, top, width, height }) {
      const image = this.$refs.mainImageRight;
      const container = this.$refs.imageRight;
      if (!image || !container) return {};

      const scaleX = container.clientWidth / image.naturalWidth;
      const scaleY = container.clientHeight / image.naturalHeight;
      const scale = Math.min(scaleX, scaleY);

      const renderedWidth = image.naturalWidth * scale;
      const renderedHeight = image.naturalHeight * scale;

      const offsetX = (container.clientWidth - renderedWidth) / 2;
      const offsetY = (container.clientHeight - renderedHeight) / 2;

      return {
        position: "absolute",
        left: `${left * scale + offsetX}px`,
        top: `${top * scale + offsetY}px`,
        width: `${width * scale}px`,
        height: `${height * scale}px`,
        border: "2px solid #FF0000",
        boxSizing: "border-box",
      };
    },

    /* 关闭病害对比弹窗 */
    viewCancel() {
      this.viewVisible = false;
      this.rectsLeft = [];
      this.rectsRight = [];
      this.dialogImgRight = {};
      this.dialogImgLeft = {};
    },
  },
};
</script>

<style lang="scss" scoped>
.surface-content {
  width: 100%;
  height: calc(100vh - 5.3rem);
}

.surface-form {
  width: 100%;
  height: 6%;
  padding-top: 0.5rem;
}

.surface-map {
  height: 94%;
  width: 100%;
  display: flex;

  .surface-div {
    width: 50%;
    height: 100%;
    padding: 0.5rem;
  }
}

// 弹窗图片框
.dialog-div {
  display: flex;
  .img-div {
    width: 50%;
    height: 25rem;
    margin: 0 1rem;
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;

    img {
      // height: 30rem;
      // width: 32rem;
      max-width: 100%;
      max-height: 100%;
      object-fit: contain;
    }

    .rect-overlay {
      position: absolute;
      pointer-events: none;
      border: 2px solid red;
    }
  }
}
</style>
