<template>
  <div class="blastDelta">
    <!-- <div class="blast-title">爆炸三角形</div> -->
    <div ref="coord" class="coords">
      <div class="coord-lineY">
        <div :style="{ width: '5px', height: `${lengY}px`, 'border-top': '1px solid #0079ff' }" v-for="item in 10" :key="item"></div>
      </div>
      <div class="coord-labelY">
        <div :style="{ width: '20px', height: `${lengY}px`, color: '#fff' }" v-for="(ite, ind) in 10" :key="ind">{{ ind == 0 ? maxY : '' }}</div>
      </div>
      <div class="coord-lineX">
        <div :style="{ height: '5px', width: `${lengY}px`, 'border-right': '1px solid #0079ff' }" v-for="item in 15" :key="item"></div>
      </div>
      <div class="coord-labelX">
        <div :style="{ height: '20px', width: `${lengY}px`, color: '#fff' }" v-for="(ite, ind) in 15" :key="ind">{{ ind == 14 ? maxX : '' }}</div>
      </div>
      <div class="line-AB" :style="{ width: 'calc(100% - 10px)', height: 'calc(100% - 10px)' }">
        <canvas id="myCanvas" :width="canvasSize.width" :height="canvasSize.height"></canvas>
      </div>
      <!-- <div class="line-legend">
        <div class="legend-ite" v-for="ite in 4" :key="ite"></div>
      </div>
      <div class="legend-name">
        <div class="item-name" v-for="item in legendList" :key="item">{{ item.name }}</div>
      </div> -->
    </div>
    <div class="line-legend">
      <div class="legend-box" v-for="(item, index) in legendList" :key="index">
        <span class="legend-icon"></span>
        <span class="legend-label">{{ item.name }}</span>
      </div>
    </div>
  </div>
</template>

<script lang="ts" setup>
  import { ref, reactive, onMounted, watch, nextTick, onUnmounted } from 'vue';

  // 类型定义
  interface Point {
    x: number;
    y: number;
  }

  interface Coordinate {
    x: number;
    y: number;
  }

  interface PolygonData {
    points: Point[];
    color: string;
  }

  interface BlastTriangleData {
    A_x: number;
    A_y: number;
    B_x: number;
    B_y: number;
    E_x: number;
    E_y: number;
    F_x: number;
    F_y: number;
    G_x: number;
    G_y: number;
  }

  const props = defineProps({
    posMonitor: {
      type: Object,
      default: () => ({}),
    },
    canvasSize: {
      type: Object,
      default: () => ({ width: 348, height: 245 }),
    },
  });

  // 响应式数据
  const coord = ref<HTMLElement | null>(null);
  const lengY = ref(0);
  const maxY = ref(0);
  const maxX = ref(0);
  const monitorPoint = reactive({ x: 0, y: 0 });

  // 爆炸三角形坐标点
  const coordinates = reactive({
    A: { x: 0, y: 0 },
    B: { x: 0, y: 0 },
    E: { x: 0, y: 0 },
    F: { x: 0, y: 0 },
    G: { x: 0, y: 0 },
  });

  const legendList = ref([{ name: '不爆炸' }, { name: '可燃气体不足' }, { name: '可爆炸' }, { name: '氧气不足' }]);

  // 工具函数
  const getAxisLength = () => {
    if (coord.value) {
      const height = coord.value.offsetHeight;
      lengY.value = Math.ceil((height - 10) / 10);
    }
  };

  const getCoordABY = (x: number): number => {
    const { A, B } = coordinates;
    // 防止除零错误
    if (B.x === A.x) return A.y;

    return Math.ceil(((B.y - A.y) * x - A.x * B.y + B.x * A.y) / (B.x - A.x));
  };

  // const getCoordABX = (y: number): number => {
  //   const { A, B } = coordinates;
  //   // 防止除零错误
  //   if (B.y === A.y) return A.x;

  //   return Math.floor(((B.x - A.x) * y + A.x * B.y - B.x * A.y) / (B.y - A.y));
  // };

  // Canvas 绘图辅助函数
  const getCanvasContext = (): CanvasRenderingContext2D | null => {
    const canvas = document.getElementById('myCanvas') as HTMLCanvasElement;
    return canvas ? canvas.getContext('2d') : null;
  };

  const drawPointMarker = (ctx: CanvasRenderingContext2D, x: number, y: number, label: string, offsetX: number = 10, offsetY: number = 0) => {
    ctx.beginPath();
    ctx.arc(x, y, 1, 0, 2 * Math.PI);
    ctx.fillStyle = '#eee';
    ctx.fill();

    ctx.font = '12px Arial';
    ctx.fillStyle = '#fff';
    ctx.fillText(label, x + offsetX, y + offsetY);
  };

  const drawMonitorPoint = (ctx: CanvasRenderingContext2D, x: number, y: number) => {
    ctx.beginPath();
    ctx.arc(x, y, 5, 0, 2 * Math.PI);
    ctx.fillStyle = 'blue';
    ctx.fill();
  };

  const drawPolygon = (ctx: CanvasRenderingContext2D, polygonData: PolygonData) => {
    ctx.beginPath();
    ctx.moveTo(polygonData.points[0].x, polygonData.points[0].y);

    for (let i = 1; i < polygonData.points.length; i++) {
      ctx.lineTo(polygonData.points[i].x, polygonData.points[i].y);
    }

    ctx.closePath();
    ctx.fillStyle = polygonData.color;
    ctx.fill();
    ctx.strokeStyle = 'transparent';
    ctx.lineWidth = 1;
    ctx.stroke();
  };

  // 主绘图函数
  const drawExplosionTriangle = () => {
    const ctx = getCanvasContext();
    if (!ctx) return;

    const canvas = ctx.canvas;

    // 计算最大坐标值
    maxY.value = getCoordABY(0);
    const maxXValue = coordinates.B.x < 50 ? 50 : Math.ceil(coordinates.B.x + 10);
    maxX.value = maxXValue;

    // 计算缩放比例
    const scaleY = canvas.height / maxY.value;
    const scaleX = canvas.width / maxXValue;

    // 坐标转换函数
    const transformPoint = (point: Coordinate): Point => ({
      x: point.x * scaleX,
      y: canvas.height - point.y * scaleY,
    });

    // 转换所有关键点
    const points = {
      A: transformPoint(coordinates.A),
      B: transformPoint(coordinates.B),
      E: transformPoint(coordinates.E),
      F: transformPoint(coordinates.F),
      G: transformPoint(coordinates.G),
      C: {
        x: maxXValue * scaleX,
        y: canvas.height - getCoordABY(maxXValue) * scaleY,
      },
      origin: { x: 0, y: canvas.height },
      maxYPoint: { x: 0, y: canvas.height - maxY.value * scaleY },
      maxXPoint: { x: maxXValue * scaleX, y: canvas.height },
      monitor: {
        x: monitorPoint.x * scaleX,
        y: canvas.height - monitorPoint.y * scaleY,
      },
    };

    // 清空画布
    ctx.clearRect(0, 0, canvas.width, canvas.height);

    // 定义多边形区域
    const polygons: PolygonData[] = [
      {
        points: [points.G, points.E, points.A, points.maxYPoint],
        color: 'rgba(1, 127, 2, 0.9)',
      },
      {
        points: [points.origin, points.F, points.E, points.G],
        color: 'rgba(127, 254, 2, 0.9)',
      },
      {
        points: [points.F, points.maxXPoint, points.C, points.B, points.E],
        color: 'rgba(255, 255, 0, 0.9)',
      },
      {
        points: [points.E, points.B, points.A],
        color: 'rgba(255, 0, 0, 0.9)',
      },
    ];

    // 绘制所有多边形
    polygons.forEach((polygon) => drawPolygon(ctx, polygon));

    // 绘制标记点
    drawPointMarker(ctx, points.A.x, points.A.y, 'A');
    drawPointMarker(ctx, points.B.x, points.B.y, 'B');
    drawPointMarker(ctx, points.E.x, points.E.y, 'E', 5, 10);
    drawPointMarker(ctx, points.G.x, points.G.y, 'G', 5);
    drawPointMarker(ctx, points.F.x, points.F.y, 'F', 10, -10);

    // 绘制监控点
    drawMonitorPoint(ctx, points.monitor.x, points.monitor.y);
  };

  const drawNonExplosionTriangle = () => {
    const ctx = getCanvasContext();
    if (!ctx) return;

    const canvas = ctx.canvas;

    // 固定坐标值
    maxY.value = 21;
    maxX.value = 50;

    // 计算缩放比例
    const scaleY = canvas.height / maxY.value;
    const scaleX = canvas.width / maxX.value;

    // 关键点
    const points = {
      A: { x: 0, y: canvas.height - maxY.value * scaleY },
      B: { x: maxX.value * scaleX, y: canvas.height },
      origin: { x: 0, y: canvas.height },
      monitor: {
        x: monitorPoint.x * scaleX,
        y: canvas.height - monitorPoint.y * scaleY,
      },
    };

    // 清空画布
    ctx.clearRect(0, 0, canvas.width, canvas.height);

    // 绘制三角形
    const polygon: PolygonData = {
      points: [points.origin, points.A, points.B],
      color: 'rgba(127, 254, 2, 0.9)',
    };
    drawPolygon(ctx, polygon);

    // 绘制标记点
    drawPointMarker(ctx, points.A.x, points.A.y, 'A', 10, 10);
    drawPointMarker(ctx, points.B.x, points.B.y, 'B', -10, -10);

    // 绘制监控点
    drawMonitorPoint(ctx, points.monitor.x, points.monitor.y);
  };

  // 数据处理函数
  const updateMonitorPoint = (data: any) => {
    monitorPoint.y = parseFloat(data.o2val) || 0;
    monitorPoint.x =
      (parseFloat(data.coval) || 0) * 0.0001 +
      (parseFloat(data.gasval) || 0) +
      (parseFloat(data.ch2val) || 0) * 0.0001 +
      (parseFloat(data.chval) || 0) * 0.0001;
  };

  const updateCoordinates = (blastData: BlastTriangleData) => {
    coordinates.A.x = blastData.A_x || 0;
    coordinates.A.y = blastData.A_y || 0;
    coordinates.B.x = blastData.B_x || 0;
    coordinates.B.y = blastData.B_y || 0;
    coordinates.E.x = blastData.E_x || 0;
    coordinates.E.y = blastData.E_y || 0;
    coordinates.F.x = blastData.F_x || 0;
    coordinates.F.y = blastData.F_y || 0;
    coordinates.G.x = blastData.G_x || 0;
    coordinates.G.y = blastData.G_y || 0;
  };

  const shouldDrawExplosionTriangle = (): boolean => {
    const { A, B } = coordinates;
    // 检查斜率是否存在且不为1，且不是垂直线
    const slope = (A.y - B.y) / (A.x - B.x);
    return !isNaN(slope) && slope !== 1 && A.x !== B.x;
  };

  // 监听和生命周期
  watch(
    () => props.posMonitor,
    (newValue) => {
      if (newValue?.btTriBlast) {
        try {
          // 更新监控点坐标
          updateMonitorPoint(newValue);

          // 解析爆炸三角形数据
          const blastData: BlastTriangleData = JSON.parse(newValue.btTriBlast);
          updateCoordinates(blastData);

          // 决定绘制哪种三角形
          const drawExplosion = shouldDrawExplosionTriangle();

          nextTick(() => {
            drawExplosion ? drawExplosionTriangle() : drawNonExplosionTriangle();
          });
        } catch (error) {
          console.error('解析爆炸三角形数据失败:', error);
        }
      }
    },
    { deep: true, immediate: true }
  );

  onMounted(() => {
    getAxisLength();

    // 可选：添加resize监听
    window.addEventListener('resize', getAxisLength);
  });

  // 清理
  onUnmounted(() => {
    window.removeEventListener('resize', getAxisLength);
  });
</script>

<style lang="less" scoped>
  .blastDelta {
    position: relative;
    width: 100%;
    height: 100%;

    // .blast-title {
    //   position: absolute;
    //   left: 50%;
    //   top: 24px;
    //   transform: translate(-50%, 0);
    //   font-size: 12px;
    //   color: #fff;
    // }

    .line-legend {
      position: absolute;
      left: 50%;
      top: 20px;
      width: 75%;
      height: 20px;
      transform: translate(-50%, 0);
      display: flex;
      justify-content: space-around;

      .legend-box {
        display: flex;

        height: 100%;
        justify-content: center;
        align-items: center;
        font-size: 12px;

        &:nth-child(1) {
          flex: 1;

          .legend-icon {
            width: 10px;
            height: 10px;
            background-color: #7ffe02;
            margin-right: 5px;
          }
        }

        &:nth-child(2) {
          flex: 1.5;

          .legend-icon {
            width: 10px;
            height: 10px;
            background-color: #017f02;
            margin-right: 5px;
          }
        }

        &:nth-child(3) {
          flex: 1;

          .legend-icon {
            width: 10px;
            height: 10px;
            background-color: #ff0000;
            margin-right: 5px;
          }
        }

        &:nth-child(4) {
          flex: 1;

          .legend-icon {
            width: 10px;
            height: 10px;
            background-color: #ffff00;
            margin-right: 5px;
          }
        }
      }
    }

    .coords {
      position: absolute;
      left: 50%;
      top: 50%;
      width: 90%;
      height: 80%;
      border-left: 1px solid #006c9d;
      border-bottom: 1px solid #006c9d;
      transform: translate(-45%, -46%);

      .coord-lineY {
        position: absolute;
        left: -5px;
        top: 10px;
        width: 5px;
        height: calc(100% - 10px);
      }

      .coord-labelY {
        position: absolute;
        left: -25px;
        top: -5px;
        width: 20px;
        height: 100%;
      }

      .coord-lineX {
        display: flex;
        position: absolute;
        bottom: -5px;
        right: 10px;
        width: calc(100% - 10px);
        height: 5px;
      }

      .coord-labelX {
        display: flex;
        justify-content: flex-end;
        position: absolute;
        bottom: -25px;
        left: -5px;
        width: 100%;
        height: 20px;
      }

      .line-AB {
        position: absolute;
        left: 0;
        top: 10px;
      }

      // .legend-name {
      //   position: absolute;
      //   right: 0;
      //   top: 20px;
      //   height: 80px;

      //   .item-name {
      //     height: 20px;
      //     line-height: 20px;
      //     font-size: 10px;
      //     color: #fff;
      //     letter-spacing: 2px;
      //   }
      // }
    }
  }
</style>
