<!--
 * @Author: SunTao 328867980@qq.com
 * @Date: 2024-10-22 15:30:25
 * @LastEditors: SunTao 328867980@qq.com
 * @LastEditTime: 2024-11-04 15:19:03
 * @FilePath: \znxjxt-ui\src\views\big-screen\components\img-dialog.vue
 * @Description: 大屏查看图片弹窗
-->

<template>
  <div class="app">
    <div class="sidebar" ref="sidebar" @scroll="handleScroll">
      <img
        v-for="(item, index) in defectData"
        :key="item.id"
        :src="item.media[0].img"
        :alt="'Image ' + (index + 1)"
        @click="showImage(index)"
        :class="{ selected: currentIndex === index }"
      />
    </div>

    <div class="main-content">
      <!-- 搜索表单 -->
      <div class="toolbar">
        <el-form
          :model="imgForm"
          ref="imgForm"
          size="small"
          :inline="true"
          label-width="5rem"
        >
          <el-row :gutter="24">
            <el-col :span="7">
              <el-form-item label="路段名称">
                <el-select
                  v-model="imgForm.segmentId"
                  placeholder="请选择路段名称"
                  :popper-append-to-body="false"
                  clearable
                >
                  <el-option
                    v-for="item in roadTypeList"
                    :key="item.value"
                    :label="item.label"
                    :value="item.value"
                  />
                </el-select>
              </el-form-item>
            </el-col>
            <el-col :span="7">
              <el-form-item label="病害类型">
                <el-select
                  v-model="imgForm.defectType"
                  placeholder="请选择路段名称"
                  :popper-append-to-body="false"
                  clearable
                >
                  <el-option
                    v-for="item in defectTypeList"
                    :key="item.value"
                    :label="item.label"
                    :value="item.value"
                  />
                </el-select>
              </el-form-item>
            </el-col>
            <el-col :span="10">
              <el-form-item label="公里桩">
                <el-input
                  v-model="imgForm.stakeStart"
                  placeholder="起始公里桩"
                  style="width: 8rem"
                  clearable
                />
                <span style="margin: 0 5px">-</span>
                <el-input
                  v-model="imgForm.stakeEnd"
                  placeholder="终止公里桩"
                  style="width: 8rem"
                  clearable
                />
              </el-form-item>
            </el-col>
          </el-row>
          <el-row>
            <el-col :span="6">
              <el-button
                type="primary"
                icon="el-icon-search"
                size="mini"
                @click="handleQuery"
                >搜索</el-button
              >
              <el-button icon="el-icon-refresh" size="mini" @click="resetQuery"
                >重置</el-button
              >
            </el-col>
          </el-row>
        </el-form>
      </div>
      <!-- 图片展示 -->
      <div class="image-viewer">
        <div class="image-container" ref="imageContainer">
          <img
            :src="currentImage"
            alt="Main Image"
            ref="mainImage"
            @load="updateRects"
          />
          <div
            class="rect-overlay"
            v-for="(rect, index) in rects"
            :key="index"
            :style="getRectStyle(rect)"
          ></div>
        </div>
        <div class="image-info">
          采集时间: {{ new Date(rectsItem.createdTime).toLocaleString() }}<br />
          起始桩号: {{ rectsItem.stakeStart || "暂无数据" }} 终止桩号:
          {{ rectsItem.stakeEnd || "暂无数据" }}<br />
          路产状态: {{ filterState(rectsItem.state) }}
        </div>
      </div>
      <!-- 小图展示 -->
      <div class="thumbnail-row">
        <img
          v-for="(mediaItem, index) in currentThumbnails"
          :key="'thumb-' + index"
          :src="mediaItem.img"
          :alt="'Thumb ' + (index + 1)"
          @click="showThumbnailImage(index)"
          :class="{ selected: selectedThumbnail === index }"
        />
      </div>
    </div>
  </div>
</template>

<script>
import { getDefectStatus } from "@/api/xj/disease";
import { defeaseList, getSegment, getItemTypes } from "@/api/xj/screen/index";
export default {
  name: "ImgDialog",
  data() {
    return {
      // 左侧图片数据
      defectData: [],
      // 当前选择的index
      currentIndex: 0,
      // 点击的index绑定
      selectedThumbnail: null,
      // 加载状态
      loading: false,
      // 表单绑定
      imgForm: {
        // 路段名称
        segmentId: "",
        // 病害类型
        defectType: "",
        // 起始公里桩
        stakeStart: "",
        // 终止公里桩
        stakeEnd: "",
      },
      // 路段下拉数据
      roadTypeList: [],
      // 病害类型下拉数据
      defectTypeList: [],
      // 分页绑定
      params: {
        page: 1,
        size: 10,
      },
      // 图片病害位置信息
      rects: [],
      // 图片下方数据
      rectsItem: {},
      // 病害状态下拉选项
      defectStatus: [],
    };
  },
  computed: {
    currentImage() {
      const thumbnails = this.currentThumbnails;
      return (
        thumbnails[this.selectedThumbnail]?.img || thumbnails[0]?.img || ""
      );
    },
    currentThumbnails() {
      return this.defectData[this.currentIndex]?.media || [];
    },
  },
  created() {
    this.getSegmentList();
    this.getDefectStatusList();
    this.getDefectType();
  },
  methods: {
    /* 查询病害状态下拉数据 */
    getDefectStatusList() {
      getDefectStatus().then(({ data, code }) => {
        if (code === 200) {
          this.defectStatus = data;
        }
      });
    },
    /* 过滤列表病害状态 */
    filterState(value) {
      let a = null;
      [a] = this.defectStatus.filter((item) => {
        return item.value === value;
      });
      if (a) {
        return a.label;
      }
    },
    /* 获取路段下拉数据 */
    getSegmentList() {
      getSegment().then(({ code, data }) => {
        if (code === 200) {
          this.roadTypeList = data;
        }
      });
    },
    /* 获取病害类型下拉数据 */
    getDefectType() {
      getItemTypes({ type: "defect" }).then(({ code, data }) => {
        if (code === 200) {
          this.defectTypeList = data;
        }
      });
    },
    /* 获取图片列表/点击搜索事件 */
    getList() {
      this.loading = true;
      const data = {
        ...this.imgForm,
        ...this.params,
      };
      defeaseList(data)
        .then((response) => {
          this.defectData.push(...response.data);
          this.loading = false;
        })
        .catch(() => {
          this.loading = false;
        });
    },
    /* 点击搜索事件 */
    handleQuery() {
      const stakeReg = /^K\d{4}\+\d{3}$/;
      if (this.imgForm.stakeStart) {
        if (stakeReg.test(this.imgForm.stakeStart)) {
          this.defectData = [];
          this.params = {
            page: 1,
            size: 10,
          };
          this.getList();
          this.showImage(0);
        } else {
          this.$modal.msgWarning("请按照'K0000+000'格式填写公里桩进行修改");
        }
      } else if (this.imgForm.stakeEnd) {
        if (stakeReg.test(this.imgForm.stakeEnd)) {
          this.defectData = [];
          this.params = {
            page: 1,
            size: 10,
          };
          this.getList();
          this.showImage(0);
        } else {
          this.$modal.msgWarning("请按照'K0000+000'格式填写公里桩进行修改");
        }
      } else {
        this.defectData = [];
        this.params = {
          page: 1,
          size: 10,
        };
        this.getList();
        this.showImage(0);
      }
    },
    /* 重置事件 */
    resetQuery() {
      this.defectData = [];
      this.imgForm = {
        segmentId: "",
        defectType: "",
        stakeStart: "",
        stakeEnd: "",
      };
      this.params = {
        page: 1,
        size: 10,
      };
      this.getList();
      this.showImage(0);
    },
    /* 左侧点击图片事件 */
    showImage(index) {
      this.currentIndex = index;
      this.selectedThumbnail = 0; // Reset to the first thumbnail when changing the main item
      this.scrollToCurrentImage();
      this.$nextTick(() => {
        this.updateRects();
      });
    },
    showThumbnailImage(index) {
      this.selectedThumbnail = index;
      this.updateRects();
    },
    scrollToCurrentImage() {
      const sidebarImages = this.$refs.sidebar.querySelectorAll("img");
      const currentImageElement = sidebarImages[this.currentIndex];
      if (currentImageElement) {
        currentImageElement.scrollIntoView({
          behavior: "smooth",
          block: "nearest",
        });
      }
    },
    /* 滚动触发事件 */
    handleScroll() {
      // 滚动高度+容器高度  滚动区域高度
      const sidebar = this.$refs.sidebar;
      if (
        sidebar.scrollTop + sidebar.clientHeight >= sidebar.scrollHeight - 1 &&
        !this.loading
      ) {
        this.loadMoreImages();
      }
    },
    /* 加载更多图片方法 */
    loadMoreImages() {
      this.params.page += 1;
      this.getList();
    },
    /* 键盘事件 */
    handleKeydown(event) {
      if (event.key === "ArrowUp") {
        if (this.currentIndex > 0) {
          this.currentIndex--;
          this.selectedThumbnail = 0; // Reset when changing main images via keyboard
          this.scrollToCurrentImage();
          this.updateRects();
        }
      } else if (event.key === "ArrowDown") {
        if (this.currentIndex <= this.defectData.length - 1) {
          this.currentIndex === this.defectData.length - 1
            ? this.currentIndex
            : this.currentIndex++;
          this.selectedThumbnail = 0; // Reset when changing main images via keyboard
          this.scrollToCurrentImage();
          this.updateRects();
        } else {
          this.loadMoreImages();
        }
      }
    },
    /* 图片位置信息获取 */
    updateRects() {
      this.rects = [];
      this.rectsItem = {};
      if (this.defectData.length > 0) {
        const image = this.$refs.mainImage;
        const rects =
          this.defectData[this.currentIndex]?.media[
            this.selectedThumbnail
          ]?.rect
            ?.split(",")
            .map(Number) || [];
        this.rects = [
          {
            left: rects[0],
            top: rects[1],
            width: rects[2],
            height: rects[3],
          },
        ];
        this.rectsItem = this.defectData[this.currentIndex];
      }
    },
    /* 图片红框位置 */
    getRectStyle({ left, top, width, height }) {
      const image = this.$refs.mainImage;
      const container = this.$refs.imageContainer;
      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",
      };
    },
  },
  mounted() {
    this.getList();
    this.showImage(0);
    window.addEventListener("keydown", this.handleKeydown);
    window.addEventListener("resize", this.updateRects);
  },
  beforeDestroy() {
    window.removeEventListener("keydown", this.handleKeydown);
    window.removeEventListener("resize", this.updateRects);
  },
};
</script>

<style lang="scss" scoped>
.app {
  width: 100%;
  display: flex;
  flex-direction: row;
  height: 45rem;
  background-color: #2e3a46;
}

.sidebar {
  width: 250px;
  background-color: #1f292e;
  padding: 10px;
  overflow-y: auto;
}

.sidebar::-webkit-scrollbar {
  width: 8px;
}

.sidebar::-webkit-scrollbar-track {
  background: #2e3a46;
  border-radius: 10px;
}

.sidebar::-webkit-scrollbar-thumb {
  background: #444c51;
  border-radius: 10px;
}

.sidebar::-webkit-scrollbar-thumb:hover {
  background: #00aaff;
}

.sidebar img {
  width: 100%;
  margin-bottom: 5px;
  cursor: pointer;
  border-radius: 3px;
  transition: transform 0.2s, border 0.2s;
  box-sizing: border-box;
}

.sidebar img.selected {
  border: 3px solid #00aaff;
  transform: scale(1.05);
}

.main-content {
  width: calc(100% - 250px);
  background-color: #1b2126;
  padding: 10px;
  display: flex;
  flex-direction: column;
}

.toolbar {
  width: 100%;
  height: 6rem;
  display: flex;
  align-items: center;
  background-color: #333c42;
  padding: 5px;
  border-bottom: 1px solid #333c42;

  ::v-deep .el-form {
    width: 100%;

    .el-form-item--small .el-form-item__label {
      color: #ffffff;
    }

    .el-select {
      width: 10rem;

      .el-input--small .el-input__inner {
        color: #ffffff;
        background-color: #333c42;
      }

      .el-select-dropdown {
        background-color: #102649;
        border-color: #08204f;
        .el-scrollbar {
          .el-select-dropdown__wrap {
            .el-scrollbar__view {
              .el-select-dropdown__item {
                color: #ffffff;
              }
              .el-select-dropdown__item:hover {
                background-color: #2b4c7e;
              }

              .el-select-dropdown__item.selected {
                background-color: #2b4c7e;
              }

              .el-select-dropdown__item.hover {
                background-color: #2b4c7e;
              }
            }

            .el-select-dropdown__list {
              background-color: #333c42;
            }
          }
        }
      }
    }

    .el-input--small .el-input__inner {
      color: #ffffff;
      background-color: #333c42;
    }
  }
}

.image-container {
  position: relative;
  width: 100%;
  height: 80%;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}

.image-container img {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
}

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

.image-viewer {
  height: 32rem;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  background-color: #22272b;
  position: relative;
}

.thumbnail-row {
  display: flex;
  justify-content: center;
  overflow-x: auto;
  padding: 10px;
  background-color: #333c42;
  gap: 10px;
}

.thumbnail-row img {
  width: 100px;
  height: 60px;
  cursor: pointer;
  border-radius: 3px;
  transition: transform 0.2s, border 0.2s;
  box-sizing: border-box;
}

.thumbnail-row img.selected {
  border: 3px solid #00aaff;
}
</style>
