<template>
  <!-- 台风图例面板 -->
  <ul class="legend" v-if="visible">
    <li>
      <span class="dot green"></span>
      <span>热带低压</span>
    </li>
    <li>
      <span class="dot blue"></span>
      <span>热带风暴</span>
    </li>
    <li>
      <span class="dot yellow"></span>
      <span>强热带风暴</span>
    </li>
    <li>
      <span class="dot orange"></span>
      <span>台风</span>
    </li>
    <li>
      <span class="dot red"></span>
      <span>超强台风</span>
    </li>
  </ul>

  <!-- 台风路径点信息弹窗 -->
  <div v-if="infoVisible && visible" class="typhoon-popup" :style="{
    left: `${popupPosition.x}px`,
    top: `${popupPosition.y}px`
  }">
    <div class="popup-content" :class="{ 'bottom': popupPosition.bottom }">
      <h3>{{ info.name }}({{ info.enname }})</h3>
      <p>{{ info.time }}</p>
      <p><strong>中心位置:</strong> {{ info.lng }}° / {{ info.lat }}°</p>
      <p><strong>风速风力:</strong> {{ info.speed }} m/s ({{ info.power }}级)</p>
      <p><strong>中心气压:</strong> {{ info.pressure }} hPa</p>
      <p><strong>移速移向:</strong> {{ info.movedirection }} {{ info.movespeed }} km/h</p>
      <p><strong>七级半径:</strong> {{ info.radius7 || '--' }}</p>
      <p><strong>十级半径:</strong> {{ info.radius10 || '--' }}</p>
      <p><strong>十二级半径:</strong> {{ info.radius12 || '--' }}</p>
      <div class="popup-arrow"></div>
    </div>
  </div>
</template>

<script setup>
import { ref, watch, nextTick, onMounted, onUnmounted } from 'vue'
import * as Cesium from 'cesium';
import axios from 'axios'

// 接收父组件传递的Cesium viewer实例和显示状态
const props = defineProps({
  viewer: {
    type: Object,
    required: false, // 不再强制要求
    default: null    // 默认值为null
  },
  visible: {
    type: Boolean,
    default: true
  },
  dataUrl: {
    type: String,
    default: '/src/assets/Data/202508.json'
  }
});

// 暴露事件
const emits = defineEmits(['onToggle']);

// 台风相关状态
const infoVisible = ref(false);
const info = ref({});
const popupPosition = ref({ x: 0, y: 0, bottom: false });
const pointDataMap = ref(new Map());
const currentEntity = ref(null);
const entityCollection = ref(null);
const tbentity = ref(null);
const iii = ref(0);
const currentPointObj = ref(null);
let typhoonInterval = null;
const fengquanLayers = ref([]);
const relatedEntities = ref({
  paths: [],
  forecasts: [],
  warnings: []
});
const popupUpdateCallback = ref(null);

// 获取Cesium容器元素
const getCesiumContainer = () => {
  return document.getElementById('cesiumContainer');
};

// 获取Cesium容器的位置信息
const getCesiumContainerRect = () => {
  const container = getCesiumContainer();
  return container ? container.getBoundingClientRect() : { left: 0, top: 0, width: 0, height: 0 };
};

// 修正updatePopupPosition函数
const updatePopupPosition = (entity) => {
  if (popupUpdateCallback.value) {
    props.viewer?.scene.postRender.removeEventListener(popupUpdateCallback.value);
    popupUpdateCallback.value = null;
  }

  if (!entity || !entity.position || !infoVisible.value || !props.viewer) return;

  popupUpdateCallback.value = () => {
    try {
      const container = getCesiumContainer();
      if (!container) return;
      
      const containerRect = container.getBoundingClientRect();
      const entityPosition = props.viewer.scene.cartesianToCanvasCoordinates(
        entity.position.getValue(props.viewer.clock.currentTime)
      );

      if (entityPosition) {
        nextTick(() => {
          const popupEl = document.querySelector('.typhoon-popup .popup-content');
          if (!popupEl) return;

          // 后续逻辑保持不变...
          const popupRect = popupEl.getBoundingClientRect();
          const popupWidth = popupRect.width;
          const popupHeight = popupRect.height;
          const arrowHeight = 10;

          const pointSize = entity.point?.pixelSize || getDynamicPointSize();
          const pointRadius = pointSize / 2;

          const offsetX = -15;
          let x = (entityPosition.x - containerRect.left) - (popupWidth / 2) + offsetX;

          let y, bottom = false;
          const topSpacing = 35;
          y = (entityPosition.y - containerRect.top) - popupHeight - arrowHeight - pointRadius - topSpacing;

          if (y < 0) {
            y = (entityPosition.y - containerRect.top) + pointRadius + arrowHeight;
            bottom = true;
          }

          if (x < 0) x = 0;
          if (x + popupWidth > containerRect.width) {
            x = containerRect.width - popupWidth;
          }

          popupPosition.value = { x, y, bottom };
        });
      }
    } catch (error) {
      console.error('更新弹窗位置时出错:', error);
    }
  };

  props.viewer.scene.postRender.addEventListener(popupUpdateCallback.value);
  popupUpdateCallback.value();
};

// 隐藏台风弹窗
const hidePopup = () => {
  infoVisible.value = false;
  if (popupUpdateCallback.value) {
    props.viewer.scene.postRender.removeEventListener(popupUpdateCallback.value);
    popupUpdateCallback.value = null;
  }
};

// 获取缩放比例
const getScaleRatio = () => {
  const designWidth = 1920;
  const designHeight = 1080;
  return Math.min(window.innerWidth / designWidth, window.innerHeight / designHeight);
};

// 获取像素比例
const getPixelRatio = () => {
  return window.devicePixelRatio || 1;
};

// 获取动态点大小
const getDynamicPointSize = () => {
  const baseSize = 8;
  const scaleRatio = getScaleRatio();
  const pixelRatio = getPixelRatio();
  return Math.max(baseSize * scaleRatio * pixelRatio, 6);
};

// 获取动态拾取半径
const getDynamicPickRadius = () => {
  const baseRadius = 10;
  const scaleRatio = getScaleRatio();
  return baseRadius * (1 / scaleRatio);
};

// 检查点是否在点击范围内
const isPointInClickRange = (clickPosition, pointPosition, radius) => {
  const dx = clickPosition.x - pointPosition.x;
  const dy = clickPosition.y - pointPosition.y;
  return Math.sqrt(dx * dx + dy * dy) <= radius;
};

// 修正checkPointClick函数
const checkPointClick = (clickPosition) => {
  if (!props.viewer || !entityCollection.value || !entityCollection.value.entities) return null;

  try {
    const radius = getDynamicPickRadius();
    const pixelRatio = getPixelRatio();
    const scaledClickPos = {
      x: clickPosition.x * pixelRatio,
      y: clickPosition.y * pixelRatio
    };

    const entities = entityCollection.value.entities.values;
    for (let i = 0; i < entities.length; i++) {
      const entity = entities[i];
      // 确保实体及其属性都存在
      if (!entity || !entity.id || !entity.position) continue;
      
      if (entity.id.startsWith('typhoon-point-')) {
        // 安全获取位置值
        const positionValue = entity.position._value || entity.position.getValue(props.viewer.clock.currentTime);
        if (!positionValue) continue;
        
        const pointPosition = props.viewer.scene.cartesianToCanvasCoordinates(positionValue);
        if (pointPosition && isPointInClickRange(scaledClickPos, pointPosition, radius)) {
          return entity;
        }
      }
    }
  } catch (error) {
    console.error('检查点击点时出错:', error);
  }

  return null;
};

// 更新台风点大小
const updatePointSizes = () => {
  if (!entityCollection.value || !entityCollection.value.entities) return;

  const newSize = getDynamicPointSize();
  const entities = entityCollection.value.entities.values;

  for (let i = 0; i < entities.length; i++) {
    const entity = entities[i];
    if (entity.id && entity.id.startsWith('typhoon-point-') && entity.point) {
      entity.point.pixelSize = newSize;
    }
  }
};

// 处理台风数据
const processPoints = (points, typhoonData) => {
  const lineArr = [];
  const pointSize = getDynamicPointSize();

  // 清除现有台风点
  if (entityCollection.value && entityCollection.value.entities) {
    entityCollection.value.entities.removeAll();
  }

  // 重新添加所有台风点
  points.forEach((element, index) => {
    const lng = Number(element.lng);
    const lat = Number(element.lat);

    let color = Cesium.Color.RED;
    switch (element.strong) {
      case "热带低压":
        color = Cesium.Color.GREEN;
        break;
      case "热带风暴":
        color = Cesium.Color.BLUE;
        break;
      case "强热带风暴":
        color = Cesium.Color.YELLOW;
        break;
      case "台风":
        color = Cesium.Color.fromCssColorString("#FBC712");
        break;
      case "强台风":
        color = Cesium.Color.PLUM;
        break;
      case "超强台风":
        color = Cesium.Color.RED;
        break;
    }

    lineArr.push(lng, lat);
    const pointId = `typhoon-point-${index}`;
    const entity = new Cesium.Entity({
      id: pointId,
      position: Cesium.Cartesian3.fromDegrees(lng, lat),
      point: {
        pixelSize: pointSize,
        color: color,
        outlineColor: Cesium.Color.WHITE,
        outlineWidth: 2,
        heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
        show: props.visible
      }
    });
    entityCollection.value.entities.add(entity);

    pointDataMap.value.set(pointId, {
      name: typhoonData.name || '',
      enname: typhoonData.enname || '',
      time: element.time || '',
      lng: element.lng,
      lat: element.lat,
      speed: element.speed,
      power: element.power,
      pressure: element.pressure,
      movedirection: element.movedirection,
      movespeed: element.movespeed,
      radius7: element.radius7 || '--',
      radius10: element.radius10 || '--',
      radius12: element.radius12 || '--'
    });
  });

  // 清除现有路径
  relatedEntities.value.paths.forEach(entity => {
    props.viewer.entities.remove(entity);
  });
  relatedEntities.value.paths = [];

  // 创建新路径
  if (lineArr.length >= 4) {
    const pathEntity = props.viewer.entities.add({
      polyline: {
        positions: Cesium.Cartesian3.fromDegreesArray(lineArr),
        width: 3,
        clampToGround: true,
        material: Cesium.Color.RED,
        show: props.visible
      }
    });
    relatedEntities.value.paths.push(pathEntity);
  }

  if (points.length > 0) {
    // 清除现有预报
    relatedEntities.value.forecasts.forEach(entity => {
      props.viewer.entities.remove(entity);
    });
    relatedEntities.value.forecasts = [];

    initForeast(points[points.length - 1]);

    // 初始化动画
    iii.value = 0;
    removes();
    adds(points, typhoonData);
  }
};

// 初始化预报
const initForeast = (data) => {
  const forecast = data.forecast || [];
  const colorArr = [
    Cesium.Color.fromCssColorString("#2D12FB"),
    Cesium.Color.fromCssColorString("#15E5E7"),
    Cesium.Color.fromCssColorString("#15E74A"),
    Cesium.Color.fromCssColorString("#E76F15"),
    Cesium.Color.fromCssColorString("#15D9E7")
  ];

  forecast.forEach((ele, ii) => {
    if (ele.forecastpoints && ele.forecastpoints.length > 0) {
      const lineArr = [];
      ele.forecastpoints.forEach(e => {
        const lng = Number(e.lng);
        const lat = Number(e.lat);
        lineArr.push(lng, lat);

        const entity = new Cesium.Entity({
          position: Cesium.Cartesian3.fromDegrees(lng, lat),
          point: {
            pixelSize: getDynamicPointSize() * 0.8,
            color: colorArr[ii % colorArr.length]
          }
        });
        entityCollection.value.entities.add(entity);
      });

      const forecastEntity = props.viewer.entities.add({
        polyline: {
          positions: Cesium.Cartesian3.fromDegreesArray(lineArr),
          width: 2,
          clampToGround: true,
          material: new Cesium.PolylineDashMaterialProperty({
            color: colorArr[ii % colorArr.length]
          })
        }
      });
      relatedEntities.value.forecasts.push(forecastEntity);
    }
  });
};

// 初始化警戒线
const initWarningLines = () => {
  // 清除现有警戒线
  relatedEntities.value.warnings.forEach(entity => {
    props.viewer.entities.remove(entity);
  });
  relatedEntities.value.warnings = [];

  // 24小时警戒线
  const line24h = props.viewer.entities.add({
    name: '24小时警戒线',
    polyline: {
      positions: Cesium.Cartesian3.fromDegreesArray([
        127, 34, 127, 22, 119, 18, 119, 11, 113, 4.5, 105, 0
      ]),
      width: 2,
      material: Cesium.Color.RED,
      clampToGround: true,
      show: props.visible
    }
  });
  relatedEntities.value.warnings.push(line24h);

  // 48小时警戒线
  const line48h = props.viewer.entities.add({
    name: '48小时警戒线',
    polyline: {
      positions: Cesium.Cartesian3.fromDegreesArray([
        132, 34, 132, 22, 119, 0, 105, 0
      ]),
      width: 2,
      material: Cesium.Color.YELLOW,
      clampToGround: true,
      show: props.visible
    }
  });
  relatedEntities.value.warnings.push(line48h);

  // 警戒线标签
  const label24h = props.viewer.entities.add({
    position: Cesium.Cartesian3.fromDegrees(126.129019, 29.104287),
    label: {
      fillColor: Cesium.Color.RED,
      text: '24小时警戒线',
      font: '14pt monospace',
      show: props.visible
    }
  });
  relatedEntities.value.warnings.push(label24h);

  const label48h = props.viewer.entities.add({
    position: Cesium.Cartesian3.fromDegrees(132, 20),
    label: {
      fillColor: Cesium.Color.YELLOW,
      text: '48小时警戒线',
      font: '14pt monospace',
      show: props.visible
    }
  });
  relatedEntities.value.warnings.push(label48h);
};

// 移除台风相关元素
const removes = () => {
  // 移除风圈
  fengquanLayers.value.forEach(entity => {
    props.viewer.entities.remove(entity);
  });
  fengquanLayers.value = [];

  // 移除风眼图标
  if (tbentity.value) {
    props.viewer.entities.remove(tbentity.value);
    tbentity.value = null;
  }
};

// 添加台风动画
const adds = (data, typhoonData) => {
  addEye(typhoonData);

  // 清除可能存在的旧定时器
  if (typhoonInterval) {
    clearInterval(typhoonInterval);
    typhoonInterval = null;
  }

  // 重置计数器
  iii.value = 0;

  // 创建新的定时器，只播放一次
  typhoonInterval = setInterval(() => {
    if (!props.visible) return;

    // 当计数器达到数据长度时，清除定时器
    if (iii.value >= data.length) {
      clearInterval(typhoonInterval);
      typhoonInterval = null;
      return;
    }

    const kkk = iii.value * 2;
    const currentData = data[iii.value];
    currentPointObj.value = {
      lon: Number(currentData.lng),
      lat: Number(currentData.lat),
      circle7: {
        radius1: 350 - kkk,
        radius2: 450 - kkk,
        radius3: 400 - kkk,
        radius4: 350 - kkk
      },
      circle10: {
        radius1: 250 - kkk,
        radius2: 270 - kkk,
        radius3: 250 - kkk,
        radius4: 220 - kkk
      },
      circle12: {
        radius1: 170 - kkk,
        radius2: 150 - kkk,
        radius3: 150 - kkk,
        radius4: 170 - kkk
      }
    };

    if (tbentity.value) {
      tbentity.value.position = Cesium.Cartesian3.fromDegrees(
        Number(currentData.lng),
        Number(currentData.lat)
      );
    }

    // 继续下一个帧
    iii.value++;
    removeTFLayer();
    if (props.visible) {
      addTyphoonCircle();
    }
  }, 200);
};

// 添加台风眼
const addEye = (typhoonData) => {
  const SuperGif = window.SuperGif;
  if (typeof SuperGif !== 'function') {
    console.warn('SuperGif未加载成功，使用默认标记');
    useDefaultMarker(typhoonData);
    return;
  }

  const img = document.createElement('img');
  img.src = '/tf.gif';

  img.onload = () => {
    try {
      const rub = new SuperGif({ gif: img });
      rub.load(() => {
        tbentity.value = props.viewer.entities.add({
          position: Cesium.Cartesian3.fromDegrees(
            Number(typhoonData.centerlng || 123.75),
            Number(typhoonData.centerlat || 28.95)
          ),
          billboard: {
            image: new Cesium.CallbackProperty(() => {
              return rub.get_canvas().toDataURL('image/png');
            }, false),
            scale: 0.1 * getScaleRatio(),
            show: props.visible
          }
        });
      });
    } catch (error) {
      console.error('GIF处理失败，使用默认标记', error);
      useDefaultMarker(typhoonData);
    }
  };

  img.onerror = () => {
    console.error('GIF加载失败，使用默认标记');
    useDefaultMarker(typhoonData);
  };
};

// 使用默认标记
const useDefaultMarker = (typhoonData) => {
  tbentity.value = props.viewer.entities.add({
    position: Cesium.Cartesian3.fromDegrees(
      Number(typhoonData.centerlng || 123.75),
      Number(typhoonData.centerlat || 28.95)
    ),
    point: {
      pixelSize: getDynamicPointSize() * 1.5,
      color: Cesium.Color.RED,
      outlineColor: Cesium.Color.WHITE,
      outlineWidth: 2,
      show: props.visible
    }
  });
};

// 移除台风风圈图层
const removeTFLayer = () => {
  fengquanLayers.value.forEach(entity => {
    props.viewer.entities.remove(entity);
  });
  fengquanLayers.value = [];
};

// 添加台风风圈
const addTyphoonCircle = () => {
  if (!currentPointObj.value || !props.visible) return;

  const circles = ['circle7', 'circle10', 'circle12'];
  circles.forEach(item => {
    const entity = props.viewer.entities.add({
      id: `tf_polygon_${item}`,
      polygon: {
        hierarchy: new Cesium.CallbackProperty(() => {
          const points = currentPointObj.value[item]
            ? getTyphoonPolygonPoints(currentPointObj.value, item)
            : [];
          return new Cesium.PolygonHierarchy(
            Cesium.Cartesian3.fromDegreesArray(points)
          );
        }, false),
        material: Cesium.Color.ORANGE.withAlpha(0.05),
        extrudedHeight: 1000,
        outline: true,
        outlineColor: Cesium.Color.ORANGE,
        outlineWidth: 2,
        show: props.visible
      },
      polyline: {
        positions: new Cesium.CallbackProperty(() => {
          const points = currentPointObj.value[item]
            ? getTyphoonPolygonPoints(currentPointObj.value, item)
            : [];
          return Cesium.Cartesian3.fromDegreesArray(points);
        }, false),
        material: Cesium.Color.ORANGE,
        width: 2,
        height: 1000,
        show: props.visible
      }
    });
    fengquanLayers.value.push(entity);
  });
};

// 获取台风风圈多边形点
const getTyphoonPolygonPoints = (pointObj, cNum) => {
  const points = [];
  const center = [Number(pointObj.lon), Number(pointObj.lat)];
  const radiusList = [
    pointObj[cNum].radius1,
    pointObj[cNum].radius2,
    pointObj[cNum].radius3,
    pointObj[cNum].radius4
  ];
  const startAngleList = [0, 90, 180, 270];
  let fx, fy;

  startAngleList.forEach((startAngle, index) => {
    const radius = radiusList[index] / 100;
    const pointNum = 90;
    const endAngle = startAngle + 90;

    for (let i = 0; i <= pointNum; i++) {
      const angle = startAngle + ((endAngle - startAngle) * i) / pointNum;
      const sin = Math.sin((angle * Math.PI) / 180);
      const cos = Math.cos((angle * Math.PI) / 180);
      const x = center[0] + radius * sin;
      const y = center[1] + radius * cos;
      points.push(x, y);

      if (startAngle === 0 && i === 0) {
        fx = x;
        fy = y;
      }
    }
  });

  points.push(fx, fy);
  return points;
};

// 加载台风数据
const loadTyphoonData = () => {
  const jsonUrl = new URL(props.dataUrl, import.meta.url).href;

  axios.get(jsonUrl)
    .then(response => {
      const typhoonData = response.data;
      processPoints(typhoonData.points, typhoonData);
      updatePointSizes();
    })
    .catch(error => {
      console.error('加载台风JSON数据失败，使用测试数据', error);
      const testTyphoonData = {
        "name": "竹节草",
        "enname": "CO-MAY",
        "points": [
          {
            "time": "2025-07-23 14:00:00",
            "lng": "119.20",
            "lat": "18.40",
            "strong": "热带低压",
            "power": "7",
            "speed": "15",
            "pressure": "998",
            "movespeed": "14",
            "movedirection": "南西",
            "radius7": "180|120|200|150",
            "radius10": "",
            "radius12": "",
            "forecast": [
              {
                "tm": "中国",
                "forecastpoints": [
                  { "lng": 121, "lat": 19 },
                  { "lng": 122, "lat": 18 }
                ]
              }
            ]
          },
          {
            "time": "2025-07-23 17:00:00",
            "lng": "119.10",
            "lat": "18.00",
            "strong": "热带低压",
            "power": "7",
            "speed": "15",
            "pressure": "996",
            "movespeed": "13",
            "movedirection": "南南西",
            "radius7": "180|120|200|150",
            "radius10": "",
            "radius12": "",
            "forecast": []
          }
        ]
      };
      processPoints(testTyphoonData.points, testTyphoonData);
      updatePointSizes();
    });
};

// 初始化台风可视化
const initVisualization = () => {
  // 确保viewer存在
  if (!props.viewer) return;
  
  // 清除可能存在的旧实体集合
  if (entityCollection.value) {
    props.viewer.dataSources.remove(entityCollection.value);
    entityCollection.value = null;
  }
  
  // 重新创建实体集合
  entityCollection.value = new Cesium.CustomDataSource("typhoonPoints");
  props.viewer.dataSources.add(entityCollection.value);

  // 清除并重新初始化警戒线
  relatedEntities.value.warnings.forEach(entity => {
    if (entity && props.viewer && Cesium.defined(entity.id)) {
      props.viewer.entities.remove(entity);
    }
  });
  relatedEntities.value.warnings = [];
  initWarningLines();

  // 重新加载台风数据
  loadTyphoonData();
};

const cleanupEntities = () => {
  if (!props.viewer) return;
  
  // 使用try-catch确保每个清理步骤都能执行
  try {
    // 清理路径实体
    relatedEntities.value.paths.forEach(entity => {
      if (entity && Cesium.defined(entity.id)) {
        props.viewer.entities.remove(entity);
      }
    });
    relatedEntities.value.paths = [];
  } catch (error) {
    console.error("清理路径实体时出错:", error);
  }
  
  try {
    // 清理警戒线实体
    relatedEntities.value.warnings.forEach(entity => {
      if (entity && Cesium.defined(entity.id)) {
        props.viewer.entities.remove(entity);
      }
    });
    relatedEntities.value.warnings = [];
  } catch (error) {
    console.error("清理警戒线实体时出错:", error);
  }
  
  try {
    // 清理预报实体
    relatedEntities.value.forecasts.forEach(entity => {
      if (entity && Cesium.defined(entity.id)) {
        props.viewer.entities.remove(entity);
      }
    });
    relatedEntities.value.forecasts = [];
  } catch (error) {
    console.error("清理预报实体时出错:", error);
  }
  
  try {
    // 清理风圈实体
    fengquanLayers.value.forEach(entity => {
      if (entity && Cesium.defined(entity.id)) {
        props.viewer.entities.remove(entity);
      }
    });
    fengquanLayers.value = [];
  } catch (error) {
    console.error("清理风圈实体时出错:", error);
  }
  
  try {
    // 清理台风眼实体
    if (tbentity.value && Cesium.defined(tbentity.value.id)) {
      props.viewer.entities.remove(tbentity.value);
      tbentity.value = null;
    }
  } catch (error) {
    console.error("清理台风眼实体时出错:", error);
  }
  
  try {
    // 清理实体集合
    if (entityCollection.value) {
      props.viewer.dataSources.remove(entityCollection.value);
      entityCollection.value = null;
    }
  } catch (error) {
    console.error("清理实体集合时出错:", error);
  }
};


// 监听visible属性变化
watch(() => props.visible, async (newVal, oldVal) => {
  if (newVal !== oldVal) {
    // 如果是从显示切换到隐藏，先清理所有实体
    if (!newVal) {
      cleanupEntities();
      hidePopup();
      if (typhoonInterval) {
        clearInterval(typhoonInterval);
        typhoonInterval = null;
      }
    } else {
      // 如果是从隐藏切换到显示，等待viewer准备就绪后重新初始化
      if (props.viewer) {
        // 确保清理残留实体
        cleanupEntities();
        // 等待一帧确保清理完成
        await nextTick();
        // 重新初始化
        initVisualization();
      }
    }
  }
});

// 初始化事件监听
const initEventListeners = () => {
  // 窗口大小变化事件
  window.addEventListener('resize', updatePointSizes);

  // 点击事件处理
  const handler = new Cesium.ScreenSpaceEventHandler(props.viewer.scene.canvas);
  
  // 左键点击事件 - 增加更严格的空值检查
  handler.setInputAction((click) => {
    if (!props.visible || !props.viewer) return;
    
    try {
      const scaleRatio = getScaleRatio();
      const correctedX = click.position.x / scaleRatio;
      const correctedY = click.position.y / scaleRatio;

      // 尝试标准拾取
      const pickedObject = props.viewer.scene.pick(new Cesium.Cartesian2(correctedX, correctedY));
      // 尝试自定义范围拾取台风点
      const typhoonPoint = pickedObject ? null : checkPointClick(click.position);
      const finalPickedObject = pickedObject || typhoonPoint;

      // 隐藏弹窗
      hidePopup();

      // 严格检查所有可能为undefined的环节
      if (Cesium.defined(finalPickedObject) && 
          Cesium.defined(finalPickedObject.id) && 
          typeof finalPickedObject.id === 'object' && 
          'id' in finalPickedObject.id) {
          
        const entityId = finalPickedObject.id.id;
        // 确保entityId是字符串且符合我们的命名规范
        if (typeof entityId === 'string' && entityId.startsWith('typhoon-point-')) {
          const data = pointDataMap.value.get(entityId);
          if (data) {
            currentEntity.value = finalPickedObject.id;
            info.value = data;
            infoVisible.value = true;
            updatePopupPosition(finalPickedObject.id);
            
            props.viewer.flyTo(finalPickedObject.id, {
              offset: new Cesium.HeadingPitchRange(0, -0.5, 1500)
            });
          }
        }
      } else {
        currentEntity.value = null;
      }
    } catch (error) {
      console.error('处理点击事件时出错:', error);
      currentEntity.value = null;
      hidePopup();
    }
  }, Cesium.ScreenSpaceEventType.LEFT_CLICK);

  // 鼠标移动事件 - 增加异常捕获
  handler.setInputAction((movement) => {
    if (!props.visible || !props.viewer) {
      hidePopup();
      return;
    }

    try {
      const scaleRatio = getScaleRatio();
      const correctedX = movement.endPosition.x / scaleRatio;
      const correctedY = movement.endPosition.y / scaleRatio;

      const pickedObject = props.viewer.scene.pick(new Cesium.Cartesian2(correctedX, correctedY));
      const typhoonPoint = pickedObject ? null : checkPointClick(movement.endPosition);
      const finalPickedObject = pickedObject || typhoonPoint;

      if (Cesium.defined(finalPickedObject) && 
          Cesium.defined(finalPickedObject.id) && 
          typeof finalPickedObject.id === 'object' && 
          'id' in finalPickedObject.id) {
          
        const entityId = finalPickedObject.id.id;
        if (typeof entityId === 'string' && entityId.startsWith('typhoon-point-')) {
          const typhoonData = pointDataMap.value.get(entityId);
          if (typhoonData) {
            currentEntity.value = finalPickedObject.id;
            info.value = typhoonData;
            infoVisible.value = true;
            updatePopupPosition(finalPickedObject.id);
            return;
          }
        }
      }

      hidePopup();
    } catch (error) {
      console.error('处理鼠标移动事件时出错:', error);
      hidePopup();
    }
  }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);

  return handler;
};

// 组件挂载时初始化
onMounted(() => {
  if (props.viewer) {
    const handler = initEventListeners();
    
    // 初始加载台风数据
    if (props.visible) {
      initVisualization();
    }

    // 在组件卸载时清理事件处理器
    onUnmounted(() => {
      if (handler) {
        handler.destroy();
      }
    });
  }
});

// 组件卸载时清理
onUnmounted(() => {
  // 清除定时器
  if (typhoonInterval) {
    clearInterval(typhoonInterval);
  }

  // 移除弹窗更新回调
  if (popupUpdateCallback.value) {
    props.viewer.scene.postRender.removeEventListener(popupUpdateCallback.value);
  }

  // 移除事件监听
  window.removeEventListener('resize', updatePointSizes);

  // 清理所有实体
  if (entityCollection.value) {
    props.viewer.dataSources.remove(entityCollection.value);
  }
  
  relatedEntities.value.paths.forEach(entity => {
    props.viewer.entities.remove(entity);
  });
  
  relatedEntities.value.forecasts.forEach(entity => {
    props.viewer.entities.remove(entity);
  });
  
  relatedEntities.value.warnings.forEach(entity => {
    props.viewer.entities.remove(entity);
  });
  
  removes();
});

// 暴露切换台风显示状态的方法
const toggleTyphoon = () => {
  emits('onToggle', !props.visible);
};

defineExpose({
  toggleTyphoon
});
</script>

<style scoped>
/* 台风图例样式 */
.legend {
  position: absolute;
  z-index: 100;
  bottom: 30px;
  right: 10px;
  color: #fff;
  background: rgba(0, 0, 0, 0.8);
  list-style: none;
  padding: 10px 15px;
  border-radius: 4px;
  margin: 0;
  transition: opacity 0.3s ease, transform 0.3s ease;
}

.legend li {
  display: flex;
  align-items: center;
  margin: 5px 0;
}

.dot {
  border-radius: 50%;
  width: 10px;
  height: 10px;
  display: inline-block;
  margin-right: 8px;
}

.green {
  background: green;
}

.blue {
  background: blue;
}

.yellow {
  background: yellow;
}

.orange {
  background: #FBC712;
}

.red {
  background: red;
}

/* 台风弹窗样式 */
.typhoon-popup {
  position: absolute;
  z-index: 1000;
  pointer-events: none;
  top: 0;
  left: 0;
}

.popup-content {
  background-color: white;
  border-radius: 5px;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2);
  padding: 10px 15px;
  width: 240px;
  pointer-events: all;
  min-width: 200px;
  box-sizing: border-box;
  position: relative;
}

.popup-arrow {
  position: absolute;
  width: 0;
  height: 0;
  border-left: 10px solid transparent;
  border-right: 10px solid transparent;
  left: 50%;
  transform: translateX(-50%);
}

/* 上方弹窗的箭头（指向下方节点） */
.popup-content:not(.bottom) .popup-arrow {
  bottom: -10px;
  border-top: 10px solid white;
}

/* 下方弹窗的箭头（指向上方节点） */
.popup-content.bottom .popup-arrow {
  top: -10px;
  border-bottom: 10px solid white;
}

.popup-content h3 {
  margin-top: 0;
  margin-bottom: 8px;
  color: #333;
  font-size: 16px;
}

.popup-content p {
  margin: 5px 0;
  color: #666;
  font-size: 14px;
}

/* 响应式调整 */
@media (max-width: 1200px) {
  .legend {
    padding: 5px 10px;
  }

  .legend li {
    font-size: 12px;
    margin: 3px 0;
  }
}

@media (max-width: 768px) {
  .popup-content {
    width: 200px;
    padding: 8px 12px;
  }

  .popup-content h3 {
    font-size: 14px;
  }

  .popup-content p {
    font-size: 12px;
    margin: 3px 0;
  }
}

/* 高DPI屏幕适配 */
@media (min-resolution: 192dpi) {
  .popup-content {
    transform: scale(0.95);
  }

  .popup-content.bottom {
    transform-origin: center bottom;
  }
}
</style>
