<template>
  <div>
    <!-- <div class="tool-actions">
      <el-tooltip content="删除" placement="top">
        <el-button
          style="position: absolute; top: 22%; right: 79%; z-index: 999"
          type="danger"
          circle
          @click="clearAll"
          :disabled="regions.length === 0"
        >
          <i class="el-icon-delete"></i>
        </el-button>
      </el-tooltip>
    </div>
    <div class="tool-actions">
      <el-tooltip content="保存" placement="top">
        <el-button
          style="position: absolute; top: 22%; right: 83%"
          type="danger"
          icon="el-icon-document-checked"
          circle
          @click="saveRegions"
          :disabled="regions.length === 0"
        />
      </el-tooltip>
    </div> -->
    <div class="image-wrapper" ref="imageWrapper">
      <el-image
        ref="temperatureImage"
        :fit="fit"
        :preview-src-list="imageList"
        :src="imgUrl"
        @load="handleImageLoad"
        @error="handleImageLoadError"
        @dblclick="onClicked"
        @mousemove="handleMouseMove"
        @mouseleave="stopDrawingIfNeeded"
        class="temperature-image"
      >
        <div slot="placeholder" class="image-slot">
          加载中<span class="dot">...</span>
        </div>

        <div slot="error" class="image-slot">
          {{ errorTips }}
        </div>
      </el-image>

      <!-- 温度悬浮显示 -->
      <div
        v-if="hoverData"
        class="temperature-display"
        :style="{
          left: hoverData.x + 'px',
          top: hoverData.y + 'px',
        }"
      >
        {{ hoverData.temperature }}°C
      </div>
    </div>
  </div>
</template>

<script>
// import { ftpImageViewUrl } from "@/utils/index";
import { mapGetters } from "vuex";
import { getConfigByKeys } from "@/api/system/config";
import Papa from "papaparse";
// 接口
import {
  selectBoxData,
  clearBoxData,
  addBoxData,
  downloadCsv,
} from "@/api/basedata/patrolpointmnt/patrolpointpreset.js";
// "@/api/analysis/index";
// 临时接口
import axios from "axios";

export default {
  name: "AsyncImage",
  components: {},
  props: {
    fit: {
      type: String,
      default: "scale-down",
    },
    srcList: {
      type: Array,
      default: () => [],
    },
    src: {
      type: String,
      default: "",
    },
    errorTips: {
      type: String,
      default: "加载失败",
    },
    supportPreview: {
      type: Boolean,
      default: false,
    },
  },
  async created() {},
  data() {
    return {
      imgUrl: "",
      imgName: "",
      loading: false,
      imageList: [],
      config: null,
      uploadDialogVisible: false,
      originalImage: null,

      // 温度数据相关
      temperatureData: [],        // 存储从CSV读取的二维温度数据
      tempRows: 0,               // CSV行数
      tempCols: 0,               // CSV列数

      // 图片尺寸相关
      imageNaturalWidth: 0,      // 图片原始宽度
      imageNaturalHeight: 0,     // 图片原始高度
      displayWidth: 0,           // 图片显示宽度
      displayHeight: 0,          // 图片显示高度
      imageScale: 1,             // 图片缩放比例

      // 鼠标悬浮相关
      hoverData: null,           // 当前悬停位置的数据
      hoverTemperatureData: [], //存续从CSV读取的温度数据用于鼠标悬浮

      // 鼠标位置温度
      currentTemp: null,
      currentPos: { x: 0, y: 0 },
      showTooltip: false,
      tooltipPosition: { x: 0, y: 0 },

      // 矩形绘制 - 已注释（但保留变量）
      isDrawing: false,
      startPos: { x: 0, y: 0 },
      currentRect: { x: 0, y: 0, width: 0, height: 0 },

      // 温度区域 - 已注释（但保留变量）
      regions: [],
      selectedRegion: null,

      // 温度范围
      maxGlobalTemp: 0,
      minGlobalTemp: 0,
      // 框的终点
      secondX: 0,
      secondY: 0,
      showFrame: false, //返回不同坐标计算

      maxTempPoints: [], // 存储每个区域的最高温点坐标
    };
  },
  computed: {
    ...mapGetters(["systemParams"]),
    tooltipStyle() {
      return {
        left: `${this.tooltipPosition.x}px`,
        top: `${this.tooltipPosition.y}px`,
        position: "absolute",
        backgroundColor: "rgba(0, 0, 0, 0.8)",
        color: "white",
        padding: "5px 10px",
        borderRadius: "4px",
        fontSize: "14px",
        pointerEvents: "none",
        zIndex: 100,
        whiteSpace: "nowrap",
      };
    },
    legendGradient() {
      return {
        background: `linear-gradient(to top,
          ${this.getColorForTemp(this.minGlobalTemp)} 0%,
          ${this.getColorForTemp(
            (this.minGlobalTemp + this.maxGlobalTemp) / 2
          )} 50%,
          ${this.getColorForTemp(this.maxGlobalTemp)} 100%)`,
        height: "200px",
        borderRadius: "4px",
      };
    },
  },
  // 悬浮
  mounted() {
    setTimeout(() => {
      this.updateImageSize();
    }, 500);
    window.addEventListener("resize", this.updateImageSize);
    this.showUploadDialog();
  },
  beforeDestroy() {
    window.removeEventListener("resize", this.updateImageSize);
  },
  methods: {
    // ==================== 图片事件处理 ====================
    handleImageLoad(event) {
      const img = event.target;
      this.imageNaturalWidth = img.naturalWidth;
      this.imageNaturalHeight = img.naturalHeight;

      this.$nextTick(() => {
        this.updateImageSize();
      });

      this.$emit('imgload', {
        imgOriginalHeight: this.imageNaturalHeight,
        imgOriginalWidth: this.imageNaturalWidth
      });

      // 去除拖动鼠标图片被拖走问题
      img.draggable = false;
      img.ondragstart = () => false;
    },

    handleImageLoadError() {
      this.$emit('imgloaderror');
    },

    onClicked() {
      this.$emit('click');
    },

    showUploadDialog() {
      this.uploadDialogVisible = true;
    },

    // ==================== 鼠标交互 ====================
    handleMouseMove(event) {
      // 处理悬浮温度显示（使用最近邻插值）
      this.handleHoverShow(event);
    },

    stopDrawingIfNeeded() {
      this.showTooltip = false;
    },

    // ==================== 图片尺寸更新 ====================
    updateImageSize() {
      const imageEl = this.$refs.temperatureImage?.$el?.querySelector("img");
      if (!imageEl) {
        return;
      }

      this.originalImage = imageEl;
      const naturalWidth = imageEl.naturalWidth;
      const naturalHeight = imageEl.naturalHeight;
      const displayWidth = imageEl.clientWidth;
      const displayHeight = imageEl.clientHeight;

      // 计算正确的缩放比例
      this.imageScale = naturalWidth / displayWidth;

      // console.log("图片尺寸更新:", {
      //   实际尺寸: `${naturalWidth}×${naturalHeight}`,
      //   显示尺寸: `${displayWidth}×${displayHeight}`,
      //   缩放比例: this.imageScale,
      // });

      const container = this.$refs.imageWrapper;
      this.containerRect = container.getBoundingClientRect();

      if (this.$refs.temperatureImage) {
        this.imageSize = {
          width: naturalWidth,
          height: naturalHeight,
        };
      }
    },

    // ==================== CSV加载和解析（分块处理，避免栈溢出） ====================
    downloadAndParseCSV() {
      const data = {
        filePath: this.imgName,
      };

      downloadCsv(data)
        .then((response) => {
          const blob = response instanceof Blob ? response : new Blob([response]);
          const reader = new FileReader();

          reader.onload = (e) => {
            try {
              const csvText = e.target.result;
              this.parseCSVInChunks(csvText);
            } catch (error) {
              // this.$message.error('读取CSV出错: ' + error.message);
            }
          };

          reader.onerror = () => {
            // this.$message.error('文件读取失败');
          };

          reader.readAsText(blob);
        })
        .catch((error) => {
          // this.$message.error('下载CSV失败');
        });
    },

    // 分块解析CSV，避免栈溢出
    parseCSVInChunks(csvText) {
      try {
        const lines = csvText.split('\n');
        const tempData = [];
        let maxCols = 0;

        const BATCH_SIZE = 1000;
        let index = 0;

        const processBatch = () => {
          const endIndex = Math.min(index + BATCH_SIZE, lines.length);

          for (let i = index; i < endIndex; i++) {
            const line = lines[i].trim();
            if (!line) continue;

            const values = line.split(',').map(v => {
              const num = parseFloat(v.trim());
              return isNaN(num) ? null : num;
            });

            const validValues = values.filter(v => v !== null && isFinite(v));

            if (validValues.length > 0) {
              tempData.push(validValues);
              if (validValues.length > maxCols) {
                maxCols = validValues.length;
              }
            }
          }

          index = endIndex;

          if (index < lines.length) {
            setTimeout(processBatch, 0);
          } else {
            this.finalizeCSVData(tempData, maxCols);
          }
        };

        processBatch();

      } catch (error) {
        // this.$message.error('解析CSV出错: ' + error.message);
      }
    },

    // 最终处理CSV数据（修复栈溢出）
    finalizeCSVData(tempData, maxCols) {
      try {
        if (tempData.length === 0) {
          this.$message.warning('CSV温度数据为空');
          return;
        }

        const normalizedData = [];
        for (let i = 0; i < tempData.length; i++) {
          const row = tempData[i];
          if (row.length < maxCols) {
            const lastVal = row[row.length - 1] || 0;
            while (row.length < maxCols) {
              row.push(lastVal);
            }
          }
          normalizedData.push(row);
        }

        this.temperatureData = normalizedData;
        this.tempRows = normalizedData.length;
        this.tempCols = normalizedData[0]?.length || 0;

        // 计算温度范围（使用循环避免栈溢出）
        let minTemp = Infinity;
        let maxTemp = -Infinity;
        let count = 0;

        const sampleLimit = Math.min(normalizedData.length, 500);
        for (let i = 0; i < sampleLimit; i++) {
          const row = normalizedData[i];
          if (Array.isArray(row)) {
            const rowLimit = Math.min(row.length, 500);
            for (let j = 0; j < rowLimit; j++) {
              const val = row[j];
              if (typeof val === 'number' && !isNaN(val) && isFinite(val)) {
                if (val < minTemp) minTemp = val;
                if (val > maxTemp) maxTemp = val;
                count++;
              }
            }
          }
        }

        // console.log('温度范围:', {
        //   min: count > 0 ? minTemp : 0,
        //   max: count > 0 ? maxTemp : 0,
        //   sampleCount: count
        // });

        // 为悬停显示准备数据（使用循环避免栈溢出）
        const hoverData = [];
        const rowLimit = Math.min(normalizedData.length, 100);
        for (let i = 0; i < rowLimit; i++) {
          const row = normalizedData[i];
          if (Array.isArray(row)) {
            const colLimit = Math.min(row.length, 100);
            for (let j = 0; j < colLimit; j++) {
              const val = row[j];
              if (typeof val === 'number' && !isNaN(val) && isFinite(val)) {
                hoverData.push(val);
              }
            }
          }
        }
        this.hoverTemperatureData = hoverData;

        // this.$message.success(`成功加载 ${this.tempRows}x${this.tempCols} 温度数据`);

      } catch (error) {
        // this.$message.error('处理CSV数据出错: ' + error.message);
      }
    },

    // ==================== 最近邻插值（精确匹配温度矩阵原始值） ====================
    nearestNeighborInterpolation(data, row, col, rows, cols) {
      if (row < 0 || row > rows - 1 || col < 0 || col > cols - 1) {
        return null;
      }

      const nearestRow = Math.round(row);
      const nearestCol = Math.round(col);

      const safeRow = Math.max(0, Math.min(nearestRow, rows - 1));
      const safeCol = Math.max(0, Math.min(nearestCol, cols - 1));

      const val = parseFloat(data[safeRow]?.[safeCol]);
      return isNaN(val) ? null : val;
    },

    // ==================== 处理鼠标悬浮显示温度（使用最近邻插值） ====================
    handleHoverShow(event) {
      const imageEl = this.$refs.temperatureImage?.$el?.querySelector('img');
      if (!imageEl) return;

      if (!this.temperatureData || this.temperatureData.length === 0) {
        this.hoverData = null;
        return;
      }

      const rect = imageEl.getBoundingClientRect();

      const mouseX = event.clientX - rect.left;
      const mouseY = event.clientY - rect.top;

      const normalizedX = mouseX / rect.width;
      const normalizedY = mouseY / rect.height;

      if (normalizedX < 0 || normalizedX > 1 || normalizedY < 0 || normalizedY > 1) {
        this.hoverData = null;
        return;
      }

      const rows = this.tempRows;
      const cols = this.tempCols;

      if (rows === 0 || cols === 0) {
        this.hoverData = null;
        return;
      }

      const floatRow = normalizedY * (rows - 1);
      const floatCol = normalizedX * (cols - 1);

      const temperature = this.nearestNeighborInterpolation(
        this.temperatureData,
        floatRow,
        floatCol,
        rows,
        cols
      );

      if (temperature !== null && !isNaN(temperature) && isFinite(temperature)) {
        let tooltipX = event.clientX - rect.left + 15;
        let tooltipY = event.clientY - rect.top - 10;

        if (tooltipX + 100 > rect.width) {
          tooltipX = event.clientX - rect.left - 100;
        }
        if (tooltipY < 20) {
          tooltipY = event.clientY - rect.top + 20;
        }
        if (tooltipY + 30 > rect.height) {
          tooltipY = rect.height - 30;
        }

        this.hoverData = {
          x: tooltipX,
          y: tooltipY,
          temperature: temperature.toFixed(1),
        };
      } else {
        this.hoverData = null;
      }
    },

    // ==================== 辅助函数 ====================
    getRandomRegionColor() {
      const colors = [
        "#FF5722",
        "#2196F3",
        "#4CAF50",
        "#FFC107",
        "#9C27B0",
        "#00BCD4",
        "#8BC34A",
        "#FF9800",
        "#673AB7",
        "#3F51B5",
        "#009688",
        "#CDDC39",
      ];
      return colors[Math.floor(Math.random() * colors.length)];
    },

    hexToRgba(hex, alpha) {
      const r = parseInt(hex.slice(1, 3), 16);
      const g = parseInt(hex.slice(3, 5), 16);
      const b = parseInt(hex.slice(5, 7), 16);
      return `rgba(${r}, ${g}, ${b}, ${alpha})`;
    },

    // ==================== FTP和URL处理 ====================
    async ftpImageViewUrl(url) {
      if (url.startsWith('http://') || url.startsWith('https://')) {
        return url;
      }
      if (!this.systemParams.ftpViewAddress) {
        const systemParams = {};
        await getConfigByKeys([
          'EXTRANET_ADDRESS',
          'EXTRANET_FTP_VIEW_ADDRESS',
          'INTRANET_FTP_VIEW_ADDRESS',
          'VIRTUAL_RTC_MEDIAURL',
          'EXTRANET_MEDIA_URL',
          'INTRANET_MEDIA_URL',
          'VIRTUAL_FLV_MEDIAURL',
          'INTRANET_FLV_MEDIA_URL',
          'EXTRANET_FLV_MEDIA_URL',
        ]).then((res) => {
          res.data.forEach((x) => {
            systemParams[x.configKey] = x.configValue;
          });
          systemParams.PREFIX = location.hostname === systemParams.EXTRANET_ADDRESS
            ? 'EXTRANET'
            : 'INTRANET';
          systemParams.ftpViewAddress = systemParams[systemParams.PREFIX + '_FTP_VIEW_ADDRESS'];
          systemParams.MEDIA_URL = systemParams[systemParams.PREFIX + '_MEDIA_URL'];
          systemParams.FLV_MEDIA_URL = systemParams[systemParams.PREFIX + '_FLV_MEDIA_URL'];
        });
        return systemParams.ftpViewAddress + url;
      } else {
        return this.systemParams.ftpViewAddress + url;
      }
    },

    async getUrls(val) {
      this.imageList = [];
      const urls = [];
      for (let index = 0; index < val.length; index++) {
        const element = val[index];
        urls.push(await this.ftpImageViewUrl(element));
      }
      if (this.supportPreview) {
        this.imageList = urls;
      }
    },
  },
  watch: {
    srcList: {
      handler(val) {
        this.getUrls(val);
      },
      immediate: true,
    },
    src: {
      async handler(val) {
        if (val && val.length > 0) {
          this.imgUrl = await this.ftpImageViewUrl(val);
          // this.imgUrl = "http://192.168.1.116:18891/shaoxing/videoMonitor/app/htjc6/htjcImage//test/39357.jpg";
          this.imgName = val;

          if (this.srcList.length === 0) {
            this.getUrls([val]);
          }

          this.$nextTick(() => {
            this.downloadAndParseCSV();
          });
        } else {
          this.imgUrl = "";
        }
      },
      immediate: true,
    },
  },
};
</script>

<style scoped>
.image-slot {
  display: flex;
  justify-content: center;
  align-items: center;
  width: 100%;
  height: 100%;
  color: #ddd;
}

.image-wrapper {
  position: relative;
  border-radius: 4px;
  overflow: hidden;
  height: calc(66vh - 350px);
  display: flex;
  justify-content: center;
  align-items: center;
}

.temperature-image {
  max-width: 100%;
  max-height: 100%;
  display: block;
  cursor: default;
}

.image-slot {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  height: 100%;
  color: #909399;
  font-size: 14px;
}

.image-slot i {
  font-size: 36px;
  margin-bottom: 10px;
}

/* 温度悬浮显示 */
.temperature-display {
  position: absolute;
  padding: 6px 12px;
  border-radius: 4px;
  background-color: rgba(0, 0, 0, 0.85);
  color: #fff;
  font-weight: bold;
  font-size: 14px;
  pointer-events: none;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.3);
  transform: translateY(-100%);
  z-index: 10;
  white-space: nowrap;
  border: 1px solid rgba(255, 255, 255, 0.1);
}
</style>
