<template>
    <div ref="konvaContainer" class="intersection-map-container"></div>
</template>

<script>
import Konva from 'konva';

export default {
  name: 'IntersectionMap',
  props: {
    // 接收父组件传来的路口数据
    mapData: {
      type: Object,
      required: true
    }
  },
  data() {
    return {
      stage: null,
      layer: null,
      armsNodes: {}, // 存储四个方向的道路实例
      panelNodes: {}, // 存储中央面板的文字实例
      // 颜色配置
      C: {
        BG: '#212842', ROAD: '#3d3938', YELLOW: '#D9A73D', WHITE: '#E0E0E0',
        SIGNAL_RED: '#FF5252', SIGNAL_GREEN: '#8DF582',
        PANEL_BG: 'rgba(30, 30, 40, 0.85)', BLUE: '#448AFF'
      },
      // 尺寸配置
      sizeConfig: {
        stageSize: 900,
        laneWidth: 40,
        halfRoad: 160,
        roadWidth: 320,
        armLength: 350
      }
    };
  },
  mounted() {
    this.initKonvaStage();
    if (this.mapData && Object.keys(this.mapData).length > 0) {
      this.renderStaticConfig();
      this.updateDynamicSignals();
    }
    // 监听容器尺寸变化，自适应缩放
    this._roaPending = false;
    this._resizeObserver = new ResizeObserver(() => {
      if (!this._roaPending) {
        this._roaPending = true;
        requestAnimationFrame(() => {
          this._roaPending = false;
          this.fitToContainer();
        });
      }
    });
    this._resizeObserver.observe(this.$refs.konvaContainer);
  },
  beforeDestroy() {
    if (this._resizeObserver) {
      this._resizeObserver.disconnect();
    }
    if (this.stage) {
      this.stage.destroy();
    }
  },
  watch: {
    // 监听数据变化
    mapData: {
      handler(newData, oldData) {
        if (!newData) return;
        
        // 简单判断：如果是首次加载数据，或者配置变了，需要重新渲染静态配置
        if (!oldData || JSON.stringify(newData.armsConfig) !== JSON.stringify(oldData.armsConfig)) {
          this.renderStaticConfig();
        }
        // 每次数据变化都更新信号状态（倒计时和红绿灯）
        this.updateDynamicSignals();
      },
      deep: true // 开启深度监听
    }
  },
  methods: {
    // ================= 自适应缩放 =================
    fitToContainer() {
      if (!this.stage || !this.$refs.konvaContainer) return;
      const container = this.$refs.konvaContainer;
      const containerWidth = container.clientWidth;
      const containerHeight = container.clientHeight;
      if (containerWidth === 0 || containerHeight === 0) return;

      const designSize = this.sizeConfig.stageSize;
      const scale = Math.min(containerWidth / designSize, containerHeight / designSize);

      this.stage.width(containerWidth);
      this.stage.height(containerHeight);

      const offsetX = (containerWidth - designSize * scale) / 2;
      const offsetY = (containerHeight - designSize * scale) / 2;

      this.layer.scale({ x: scale, y: scale });
      this.layer.position({ x: offsetX, y: offsetY });
      this.layer.draw();
    },

    // ================= 初始化画布 =================
    initKonvaStage() {
      const { stageSize, halfRoad, roadWidth } = this.sizeConfig;
      const center = stageSize / 2;

      const container = this.$refs.konvaContainer;
      const initWidth = container.clientWidth || stageSize;
      const initHeight = container.clientHeight || stageSize;

      this.stage = new Konva.Stage({
        container: this.$refs.konvaContainer,
        width: initWidth,
        height: initHeight
      });
      this.layer = new Konva.Layer();
      this.stage.add(this.layer);

      // 绘制背景
      this.layer.add(new Konva.Rect({ width: stageSize, height: stageSize, fill: this.C.BG }));
      // 绘制中心路口交叉区
      this.layer.add(new Konva.Rect({ x: center - halfRoad, y: center - halfRoad, width: roadWidth, height: roadWidth, fill: this.C.ROAD }));

      // 创建四个方向的道路骨架
      this.armsNodes = {
        N: this.createRoadArm(center, center - halfRoad, 0),
        E: this.createRoadArm(center + halfRoad, center, 90),
        S: this.createRoadArm(center, center + halfRoad, 180),
        W: this.createRoadArm(center - halfRoad, center, 270)
      };
      Object.values(this.armsNodes).forEach(arm => this.layer.add(arm));

      // 创建中央面板
      this.createCenterPanel(center);
      this.layer.draw();
      this.fitToContainer();
    },

    // ================= 创建道路骨架 (内置绘制逻辑) =================
    createRoadArm(x, y, rotation) {
      const { halfRoad, roadWidth, laneWidth } = this.sizeConfig;
      const group = new Konva.Group({ x, y, rotation });
      
      // 1. 路面与线条
      group.add(new Konva.Rect({ x: -halfRoad, y: -350, width: roadWidth, height: 350, fill: this.C.ROAD }));
      group.add(new Konva.Line({ points: [0, -350, 0, -35], stroke: this.C.YELLOW, strokeWidth: 3 }));
      group.add(new Konva.Path({ data: `M -160 -350 L -160 -30 Q -160 0 -180 0`, stroke: this.C.YELLOW, strokeWidth: 3 }));
      group.add(new Konva.Path({ data: `M 160 -350 L 160 -30 Q 160 0 180 0`, stroke: this.C.YELLOW, strokeWidth: 3 }));
      group.add(new Konva.Line({ points: [-160, -35, 0, -35], stroke: this.C.WHITE, strokeWidth: 4 }));
      
      for (let i = 1; i < 4; i++) {
        let ox = i * laneWidth;
        group.add(new Konva.Line({ points: [-ox, -35, -ox, -120], stroke: this.C.WHITE, strokeWidth: 2 }));
        group.add(new Konva.Line({ points: [-ox, -120, -ox, -350], stroke: this.C.WHITE, strokeWidth: 2, dash: [15, 15] }));
        group.add(new Konva.Line({ points: [ox, -35, ox, -350], stroke: this.C.WHITE, strokeWidth: 2, dash: [15, 15] }));
      }
      
      // 2. 信号灯带容器
      const lightGroup = new Konva.Group();
      const rectOpts = { y: -16, width: 8, height: 24, cornerRadius: 2, offsetX: 4, offsetY: 12 };
      for (let lx = -148; lx <= -20; lx += 16) lightGroup.add(new Konva.Rect({ x: lx, ...rectOpts }));
      for (let rx = 20; rx <= 148; rx += 16) lightGroup.add(new Konva.Rect({ x: rx, ...rectOpts }));
      group.add(lightGroup);
      group.lightGroup = lightGroup;

      // 预留动态挂载点
      group.arrowNodes = { 0: null, 1: null, 2: null, 3: null };
      group.cameraNode = null;

      return group;
    },

    createCenterPanel(center) {
      const panelGroup = new Konva.Group({ x: center - 80, y: center - 45 });
      panelGroup.add(new Konva.Rect({ width: 160, height: 90, fill: this.C.PANEL_BG, cornerRadius: 8 }));
      
      const labelFont = { fontSize: 18, fontFamily: 'monospace', fontStyle: 'bold', fill: this.C.WHITE }; 
      const valueFont = { fontSize: 28, fontFamily: 'monospace', fontStyle: 'bold' };              
      
      this.panelNodes.nsLabel = new Konva.Text({ ...labelFont, x: 15, y: 22, text: '相位-:' });
      this.panelNodes.nsVal = new Konva.Text({ ...valueFont, x: 90, y: 15, text: '--', fill: this.C.SIGNAL_GREEN });
      
      this.panelNodes.ewLabel = new Konva.Text({ ...labelFont, x: 15, y: 55, text: '相位-:' });
      this.panelNodes.ewVal = new Konva.Text({ ...valueFont, x: 90, y: 48, text: '--', fill: this.C.SIGNAL_GREEN });
      
      panelGroup.add(this.panelNodes.nsLabel, this.panelNodes.nsVal, this.panelNodes.ewLabel, this.panelNodes.ewVal);
      this.layer.add(panelGroup);
    },

    // ================= 图标工厂函数 =================
    createArrowIcon(type, x, y, color = this.C.WHITE) {
      const group = new Konva.Group({ x, y, scaleX: 0.65, scaleY: 0.65 });
      group.add(new Konva.Circle({ x: 0, y: -35, radius: 3, fill: color, name: 'colorFill' }));
      let pathData = '';
      if (type === 'S') pathData = 'M 0 -35 L 0 0 M -7 -10 L 0 0 L 7 -10';
      else if (type === 'L') pathData = 'M 0 -35 L 0 -15 Q 0 0 15 0 M 5 -7 L 15 0 L 5 7';
      else if (type === 'R') pathData = 'M 0 -35 L 0 -15 Q 0 0 -15 0 M -5 -7 L -15 0 L -5 7';
      else if (type === 'U') pathData = 'M 0 -35 L 0 -15 Q 0 0 14 0 Q 28 0 28 -15 L 28 -25 M 21 -18 L 28 -25 L 35 -18';
      group.add(new Konva.Path({ data: pathData, stroke: color, strokeWidth: 3, lineCap: 'round', lineJoin: 'round', name: 'colorStroke' }));
      return group;
    },

    createCameraIcon(type, x, y) {
      const group = new Konva.Group({ x, y });
      if (type === 1) { 
        group.add(new Konva.Line({ points: [-16, -30, 16, -30], stroke: this.C.BLUE, strokeWidth: 2.5, lineCap: 'round' }));
        group.add(new Konva.Line({ points: [0, -30, 0, -10], stroke: this.C.BLUE, strokeWidth: 2.5 }));
        const body = new Konva.Group({ y: -10, rotation: 15 });
        body.add(new Konva.Rect({ x: -16, y: -8, width: 32, height: 16, stroke: this.C.BLUE, strokeWidth: 2.5, cornerRadius: 2 }));
        body.add(new Konva.Rect({ x: 16, y: -4, width: 6, height: 8, stroke: this.C.BLUE, strokeWidth: 2.5, cornerRadius: 1 }));
        group.add(body);
      } else if (type === 2) { 
        group.add(new Konva.Rect({ x: -14, y: -24, width: 28, height: 24, stroke: this.C.BLUE, strokeWidth: 2.5, cornerRadius: 6 }));
        group.add(new Konva.Circle({ x: 0, y: -12, radius: 5, stroke: this.C.BLUE, strokeWidth: 2.5 }));
        group.add(new Konva.Line({ points: [-10, 0, 10, 0], stroke: this.C.BLUE, strokeWidth: 2.5, lineCap: 'round' }));
        group.add(new Konva.Line({ points: [0, 0, 0, 6], stroke: this.C.BLUE, strokeWidth: 2.5 }));
      }
      return group;
    },

    // ================= 核心更新逻辑 =================
    // 渲染或更新静态设备(摄像头、箭头配置)
    renderStaticConfig() {
      const config = this.mapData.armsConfig;
      if (!config) return;

      Object.keys(config).forEach(dir => {
        const armData = config[dir];
        const armNode = this.armsNodes[dir];

        // 挂载摄像头
        if (armNode.cameraNode) armNode.cameraNode.destroy();
        if (armData.cameraType > 0) {
          const cam = this.createCameraIcon(armData.cameraType, -80, -190);
          armNode.add(cam);
          armNode.cameraNode = cam;
        }

        // 挂载车道箭头
        armData.lanes.forEach((type, index) => {
          if (armNode.arrowNodes[index]) armNode.arrowNodes[index].destroy();
          if (type) {
            const lx = -20 - (index * this.sizeConfig.laneWidth);
            const arrow = this.createArrowIcon(type, lx, -80, this.C.WHITE);
            armNode.add(arrow);
            armNode.arrowNodes[index] = arrow;
          }
        });
      });
      this.layer.draw();
    },

    // 根据实时倒计时和红绿灯更新颜色
    updateDynamicSignals() {
      const signals = this.mapData.signals;
      if (!signals) return;

      const nsColor = signals.ns.isGreen ? this.C.SIGNAL_GREEN : this.C.SIGNAL_RED;
      const ewColor = signals.ew.isGreen ? this.C.SIGNAL_GREEN : this.C.SIGNAL_RED;

      // 辅助函数：染色
      const dyeArm = (armNode, color) => {
        armNode.lightGroup.getChildren().forEach(r => r.fill(color));
        Object.values(armNode.arrowNodes).forEach(arr => {
          if (arr) {
            arr.findOne('.colorFill').fill(color);
            arr.findOne('.colorStroke').stroke(color);
          }
        });
      };

      dyeArm(this.armsNodes.N, nsColor);
      dyeArm(this.armsNodes.S, nsColor);
      dyeArm(this.armsNodes.E, ewColor);
      dyeArm(this.armsNodes.W, ewColor);

      // 更新中央面板
      this.panelNodes.nsLabel.text(`${signals.ns.phaseName}:`);
      this.panelNodes.nsVal.text(signals.ns.time.toString().padStart(2, '0')).fill(nsColor);
      
      this.panelNodes.ewLabel.text(`${signals.ew.phaseName}:`);
      this.panelNodes.ewVal.text(signals.ew.time.toString().padStart(2, '0')).fill(ewColor);

      this.layer.draw();
    }
  }
};
</script>

<style scoped>
.intersection-map-container {
  width: 100%;
  height: 100%;
}
</style>