<template>
  <div class="situational-awareness">
    <!-- 顶部导航栏 -->
    <PageHeader @back="handleBack" />

    <!-- 主内容区域 -->
    <div class="situational-awareness__main">
      <!-- 地图底层 -->
      <div
        class="situational-awareness__map-layer"
        :class="{ 'is-compare-mode': isCompareMode }"
      >
        <!-- 左侧地图容器（对比模式下显示灾前场景） -->
        <div
          id="leftCesiumContainer"
          class="situational-awareness__left-map"
        ></div>

        <!-- 中间分割线 -->
        <div
          v-if="isCompareMode"
          class="situational-awareness__center-divider"
        ></div>

        <!-- 右侧地图（主地图 - 灾后场景） -->
        <div class="situational-awareness__right-map">
          <MapViewer @tool-change="handleMapToolChange" />
        </div>
      </div>

      <!-- 地图遮罩层 -->
      <div class="situational-awareness__map-mask" aria-hidden="true"></div>

      <!-- 场景标签层 - 独立层级，显示在遮罩层之上 -->
      <div class="situational-awareness__scene-labels-layer">
        <!-- 灾前现场实景标签 - 在中间分割线左侧 -->
        <SceneLabel
          v-if="isCompareMode"
          text="灾前现场实景"
          position="center-left"
        />

        <!-- 灾后现场实景标签 - 在右侧面板左边 -->
        <SceneLabel
          text="灾后现场实景"
          position="right-left"
        />
      </div>

      <!-- 浮动面板层 -->
      <div class="situational-awareness__panels-layer">
        <Transition name="panel-slide-left">
          <div
            v-show="!isLeftPanelCollapsed"
            class="situational-awareness__panel-column situational-awareness__panel-column--left"
          >
            <LeftPanel @start-dispatch="handleStartDispatch" />
          </div>
        </Transition>

        <Transition name="panel-slide-right">
          <div
            v-show="!isRightPanelCollapsed"
            class="situational-awareness__panel-column situational-awareness__panel-column--right"
          >
            <RightPanel />
          </div>
        </Transition>
      </div>

      <!-- 折叠按钮层 -->
      <div class="situational-awareness__collapse-buttons-layer">
        <!-- 左侧折叠按钮 -->
        <button
          class="situational-awareness__collapse-btn situational-awareness__collapse-btn--left"
          :class="{ 'is-collapsed': isLeftPanelCollapsed }"
          @click="toggleLeftPanel"
          :aria-label="isLeftPanelCollapsed ? '展开左侧面板' : '收起左侧面板'"
        >
          <img
            :src="isLeftPanelCollapsed ? collapseRightArrow : collapseLeftArrow"
            alt=""
            class="collapse-arrow"
          />
        </button>

        <!-- 右侧折叠按钮 -->
        <button
          class="situational-awareness__collapse-btn situational-awareness__collapse-btn--right"
          :class="{ 'is-collapsed': isRightPanelCollapsed }"
          @click="toggleRightPanel"
          :aria-label="isRightPanelCollapsed ? '展开右侧面板' : '收起右侧面板'"
        >
          <img
            :src="isRightPanelCollapsed ? collapseLeftArrow : collapseRightArrow"
            alt=""
            class="collapse-arrow"
          />
        </button>
      </div>

      <!-- 地图控件层 - 高于遮罩和面板 -->
      <div class="situational-awareness__controls-layer">
        <div id="sa-controls" class="situational-awareness__controls"></div>
      </div>

      <!-- 地图 Tooltip 层 - 用于显示地图标记点的轻量级信息提示框 -->
      <div class="situational-awareness__tooltip-layer">
        <MapTooltip
          v-model:visible="mapTooltip.visible"
          :x="mapTooltip.x"
          :y="mapTooltip.y"
          :title="mapTooltip.title"
          :icon="mapTooltip.icon"
          :z-index="mapTooltip.zIndex"
          @close="handleMapTooltipClose"
        >
          <!-- Tooltip 内容插槽 - 根据实际业务数据渲染 -->
          <template v-if="mapTooltip.data && mapTooltip.data.fields">
            <div
              v-for="(field, index) in mapTooltip.data.fields"
              :key="index"
              class="tooltip-field-item"
            >
              <span class="tooltip-field-label">{{ field.label }}：</span>
              <span class="tooltip-field-value">{{ field.value }}</span>
            </div>
          </template>
        </MapTooltip>
      </div>

      <!-- 加载动画层 - 一键启动后显示 -->
      <div v-if="showLoading" class="situational-awareness__loading-layer">
        <img
          src="./assets/images/加载.gif"
          alt="加载中"
          class="situational-awareness__loading-gif"
        />
      </div>
    </div>

    <!-- 弹窗组件 -->
    <PersonnelDetail
      :visible="showPersonnelDetail"
      :personnel-data="selectedPersonnel"
      @close="showPersonnelDetail = false"
      @link="handlePersonnelLink"
    />

    <EmergencyCenterDetail
      :visible="showCenterDetail"
      :center-data="selectedCenter"
      @close="showCenterDetail = false"
    />
  </div>
</template>

<script setup>
import { ref, provide, onMounted } from "vue";
import * as Cesium from "cesium";
import { ElMessage } from "element-plus";
import PageHeader from "./components/PageHeader.vue";
import LeftPanel from "./components/LeftPanel/index.vue";
import MapViewer from "./components/MapViewer/index.vue";
import RightPanel from "./components/RightPanel/index.vue";
import PersonnelDetail from "./components/Popups/PersonnelDetail.vue";
import EmergencyCenterDetail from "./components/Popups/EmergencyCenterDetail.vue";
import MapTooltip from "./components/shared/MapTooltip.vue";
import SceneLabel from "./components/SceneLabel.vue";
import { useDisasterData } from "./composables/useDisasterData";
import { useDualMapCompare } from "./composables/useDualMapCompare";
import { useMapMarkers } from "./composables/useMapMarkers";
import { use3DTiles } from "./composables/use3DTiles";
import { useMapTooltip } from "./composables/useMapTooltip";
import { useMapStore } from "@/map";
import { request } from "@shared/utils/request";

// 标记点图标
import emergencyCenterIcon from "./assets/images/应急中心.png";
import eventIcon from "./assets/images/事件icon.png";
import soldierIcon from "./assets/images/SketchPngfbec927027ff9e49207749ebaafd229429315341fda199251b6dfb1723ff17fb.png";
import deviceIcon from "./assets/images/SketchPng860d54f2a31f5f441fc6a88081224f1e98534bf6d5ca1246e420983bdf690380.png";
import emergencyBaseIcon from "./assets/images/应急基地.png";
import reserveCenterIcon from "./assets/images/储备中心.png";

// 折叠按钮图标
import collapseLeftArrow from "./assets/images/折叠面板左箭头.png";
import collapseRightArrow from "./assets/images/折叠面板右箭头.png";

// 使用灾害数据
const disasterData = useDisasterData();

// 处理距离范围变更
const handleDistanceChange = async (newDistance) => {
  console.log(`[index.vue] 距离范围改变为: ${newDistance}km`);

  // 更新搜索半径
  disasterData.updateSearchRadius(newDistance);

  // 更新范围圈
  if (mapStore.viewer) {
    createOrUpdateRangeCircle(mapStore.viewer, newDistance);
  }

  // 重新加载应急资源数据并更新地图标记
  await loadEmergencyResources(108.011506, 30.175827);

  // 重新加载储备中心和预置点数据并更新地图标记
  await loadReserveCentersAndPresets(108.011506, 30.175827);
};

// 提供给子组件使用
provide("disasterData", disasterData);
provide("onDistanceChange", handleDistanceChange);

// 地图 store
const mapStore = useMapStore();

// 双地图对比功能
const { isCompareMode, toggleCompareMode } = useDualMapCompare();

// 地图标记功能
const {
  initializeMarkers,
  clearMarkers,
  getCollapseCenter,
  addEmergencyResourceMarkers,
  clearEmergencyResourceMarkers,
  addReserveCenterMarkers,
  clearReserveCenterMarkers,
} = useMapMarkers();

// 地图 Tooltip 功能
const { tooltipState: mapTooltip, showTooltip, hideTooltip, updateTooltipPosition } = useMapTooltip();

// 当前显示 tooltip 的实体（用于相机移动时更新位置）
const currentTooltipEntity = ref(null);

// 加载动画状态
const showLoading = ref(false);

// 范围圈实体
const rangeCircleEntity = ref(null);

// 面板折叠状态
const isLeftPanelCollapsed = ref(false);
const isRightPanelCollapsed = ref(false);

// 切换左侧面板
const toggleLeftPanel = () => {
  isLeftPanelCollapsed.value = !isLeftPanelCollapsed.value;
};

// 切换右侧面板
const toggleRightPanel = () => {
  isRightPanelCollapsed.value = !isRightPanelCollapsed.value;
};

// 3D Tiles加载功能
const { load3DTileset, waitForTilesetReady } = use3DTiles();

/**
 * 设置地图点击事件处理器
 * 当用户点击地图标记点时，显示 Tooltip
 */
const setupMapClickHandler = (viewer) => {
  if (!viewer) return;

  // 创建 ScreenSpaceEventHandler 监听点击事件
  const handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);

  handler.setInputAction((click) => {
    // 获取点击位置的实体
    const pickedObject = viewer.scene.pick(click.position);

    if (Cesium.defined(pickedObject) && Cesium.defined(pickedObject.id)) {
      const entity = pickedObject.id;

      // 过滤掉范围圈实体（通过检查是否是范围圈）
      if (entity === rangeCircleEntity.value) {
        console.log('[index.vue] 点击了范围圈，忽略');
        // 尝试穿透到下面的实体
        const drillPickedObjects = viewer.scene.drillPick(click.position);
        let foundMarker = false;

        for (const pickedObj of drillPickedObjects) {
          if (Cesium.defined(pickedObj.id) && pickedObj.id !== rangeCircleEntity.value) {
            const markerEntity = pickedObj.id;
            if (markerEntity.properties) {
              const type = markerEntity.properties.type?.getValue();

              // 找到标记点，显示 Tooltip
              if (type === 'soldier') {
                showMarkerTooltip(viewer, markerEntity, click.position, soldierIcon);
                foundMarker = true;
                break;
              } else if (type === 'device') {
                showMarkerTooltip(viewer, markerEntity, click.position, deviceIcon);
                foundMarker = true;
                break;
              } else if (type === 'emergencyBase' || type === 'station') {
                const stationName = markerEntity.properties.name?.getValue() || '';
                const icon = stationName === '忠县公路交通应急物资储备中心'
                  ? emergencyCenterIcon
                  : emergencyBaseIcon;
                showMarkerTooltip(viewer, markerEntity, click.position, icon);
                foundMarker = true;
                break;
              } else if (type === 'reserveCenter' || type === 'presetPoint') {
                const icon = type === 'reserveCenter' ? reserveCenterIcon : emergencyBaseIcon;
                showMarkerTooltip(viewer, markerEntity, click.position, icon);
                foundMarker = true;
                break;
              }
            }
          }
        }

        if (!foundMarker) {
          hideTooltip();
          currentTooltipEntity.value = null;
        }
        return;
      }

      // 检查实体是否有 properties（标记点才有）
      if (entity.properties) {
        const type = entity.properties.type?.getValue();

        // 根据标记类型显示不同的 Tooltip
        if (type === 'soldier') {
          showMarkerTooltip(viewer, entity, click.position, soldierIcon);
        } else if (type === 'device') {
          showMarkerTooltip(viewer, entity, click.position, deviceIcon);
        } else if (type === 'emergencyBase' || type === 'station') {
          // 对于养护站，根据名称判断使用哪个图标
          const stationName = entity.properties.name?.getValue() || '';
          const icon = stationName === '忠县公路交通应急物资储备中心'
            ? emergencyCenterIcon
            : emergencyBaseIcon;
          showMarkerTooltip(viewer, entity, click.position, icon);
        } else if (type === 'reserveCenter' || type === 'presetPoint') {
          // 储备中心和预置点
          const icon = type === 'reserveCenter' ? reserveCenterIcon : emergencyBaseIcon;
          showMarkerTooltip(viewer, entity, click.position, icon);
        }
      }
    } else {
      // 点击空白区域，隐藏 Tooltip
      hideTooltip();
      currentTooltipEntity.value = null;
    }
  }, Cesium.ScreenSpaceEventType.LEFT_CLICK);

  // 监听相机移动事件，更新 tooltip 位置
  viewer.scene.postRender.addEventListener(() => {
    if (currentTooltipEntity.value && mapTooltip.value.visible) {
      updateTooltipPositionForEntity(viewer, currentTooltipEntity.value);
    }
  });
};

/**
 * 显示标记点 Tooltip
 * @param {Cesium.Viewer} viewer - Cesium viewer 实例
 * @param {Cesium.Entity} entity - 被点击的实体
 * @param {Cesium.Cartesian2} screenPosition - 点击的屏幕坐标（备用）
 * @param {string} icon - 图标路径
 */
const showMarkerTooltip = (viewer, entity, screenPosition, icon) => {
  const properties = entity.properties;
  const type = properties.type?.getValue();

  // 获取实体的 3D 位置
  const position = entity.position?.getValue(Cesium.JulianDate.now());

  if (!position) {
    console.warn('[Tooltip] 无法获取实体位置');
    return;
  }

  // 对于使用 CLAMP_TO_GROUND 的 billboard，需要获取实际的地形高度
  const cartographic = Cesium.Cartographic.fromCartesian(position);
  let clampedPosition = position;

  // 使用 globe.getHeight 获取地形高度
  if (viewer.scene.globe) {
    const height = viewer.scene.globe.getHeight(cartographic);
    if (Cesium.defined(height)) {
      cartographic.height = height;
      clampedPosition = Cesium.Cartographic.toCartesian(cartographic);
    }
  }

  // 将贴地后的 3D 坐标转换为屏幕坐标
  const canvasPosition = viewer.scene.cartesianToCanvasCoordinates(clampedPosition);

  if (!Cesium.defined(canvasPosition)) {
    console.warn('[Tooltip] 无法转换坐标到屏幕位置');
    return;
  }

  // 构建 Tooltip 数据
  let title = '';
  const fields = [];

  if (type === 'soldier') {
    title = '单兵信息';
    fields.push(
      { label: '姓名', value: properties.name?.getValue() || '-' },
      { label: '部门', value: properties.department?.getValue() || '-' },
      { label: '位置', value: properties.location?.getValue() || '-' }
    );
  } else if (type === 'device') {
    title = '设备信息';
    fields.push(
      { label: '设备名称', value: properties.name?.getValue() || '-' },
      { label: '设备类型', value: properties.deviceType?.getValue() || '-' },
      { label: '位置', value: properties.location?.getValue() || '-' }
    );
  } else if (type === 'emergencyBase') {
    title = '应急基地';
    fields.push(
      { label: '名称', value: properties.name?.getValue() || '-' },
      { label: '地址', value: properties.address?.getValue() || '-' },
      { label: '距离', value: properties.distance?.getValue() || '-' }
    );
  } else if (type === 'station') {
    const stationName = properties.name?.getValue() || '';
    const distance = properties.distance?.getValue() || 0;

    // 如果是应急中心，显示应急中心信息
    if (stationName === '忠县公路交通应急物资储备中心') {
      title = '应急中心';
      fields.push(
        { label: '名称', value: '忠县应急中心' },
        { label: '行政等级', value: '国道' },
        { label: '隶属单位', value: '交通公路部门' },
        { label: '位置信息', value: `目前为止距离现场${distance}公里` }
      );
    } else {
      // 其他养护站显示 tooltip
      title = '养护站';
      fields.push(
        { label: '名称', value: stationName || '-' },
        { label: '距离', value: `${distance}公里` }
      );
    }
  } else if (type === 'reserveCenter') {
    // 储备中心
    title = '储备中心';
    fields.push(
      { label: '名称', value: properties.name?.getValue() || '-' },
      { label: '区县', value: properties.district?.getValue() || '-' },
      { label: '人员数量', value: properties.personnelCount?.getValue() || '0' },
      { label: '占地面积', value: properties.area?.getValue() ? `${properties.area?.getValue()}㎡` : '-' }
    );
  } else if (type === 'presetPoint') {
    // 预置点
    title = '预置点';
    fields.push(
      { label: '名称', value: properties.name?.getValue() || '-' },
      { label: '区县', value: properties.district?.getValue() || '-' },
      { label: '人员数量', value: properties.personnelCount?.getValue() || '0' }
    );
  }

  // 显示 Tooltip，使用实体的屏幕坐标
  showTooltip({
    x: canvasPosition.x,
    y: canvasPosition.y,
    title,
    icon,
    data: { fields }
  });

  // 保存当前实体，用于相机移动时更新位置
  currentTooltipEntity.value = entity;
};

/**
 * 更新 Tooltip 位置（当相机移动时）
 * @param {Cesium.Viewer} viewer - Cesium viewer 实例
 * @param {Cesium.Entity} entity - 实体对象
 */
const updateTooltipPositionForEntity = (viewer, entity) => {
  const position = entity.position?.getValue(Cesium.JulianDate.now());

  if (!position) return;

  // 对于使用 CLAMP_TO_GROUND 的 billboard，需要获取实际的地形高度
  const cartographic = Cesium.Cartographic.fromCartesian(position);
  let clampedPosition = position;

  // 使用 globe.getHeight 获取地形高度
  if (viewer.scene.globe) {
    const height = viewer.scene.globe.getHeight(cartographic);
    if (Cesium.defined(height)) {
      cartographic.height = height;
      clampedPosition = Cesium.Cartographic.toCartesian(cartographic);
    }
  }

  // 将贴地后的 3D 坐标转换为屏幕坐标
  const canvasPosition = viewer.scene.cartesianToCanvasCoordinates(clampedPosition);

  // 如果标记点在视野外，隐藏 tooltip
  if (!Cesium.defined(canvasPosition)) {
    hideTooltip();
    currentTooltipEntity.value = null;
    return;
  }

  updateTooltipPosition(canvasPosition.x, canvasPosition.y);
};

// 初始化地图
onMounted(() => {
  // 等待地图就绪后配置初始视图和模型对比图层
  mapStore.onReady(async () => {
    const { camera } = mapStore.services();
    const viewer = mapStore.viewer;

    console.log("3D态势感知地图已就绪");

    // 默认相机配置
    const DEFAULT_CAMERA_VIEW = {
      lon: 108.011506,
      lat: 30.175827,
      height: 5000,
      heading: 0,
      pitch: -45,
      roll: 0,
    };

    // 默认点加上图标标记，使用图片图标，图标路径为 packages\screen\src\views\3DSituationalAwarenessRefactor\assets\images\应急基地.png
    const defaultPoint = new Cesium.Entity({
      position: Cesium.Cartesian3.fromDegrees(
        DEFAULT_CAMERA_VIEW.lon,
        DEFAULT_CAMERA_VIEW.lat,
        0
      ),
      billboard: {
        image: eventIcon,
        width: 36,
        height: 36,
        verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
        heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
        disableDepthTestDistance: Number.POSITIVE_INFINITY,
      },
    });
    viewer.entities.add(defaultPoint);

    // 在默认点附近添加10个模拟点位（应急人员和应急装备）
    const simulatedPoints = [
      // 应急人员 (6个)
      { type: 'soldier', name: '张三', department: '应急救援队', lon: 107.97, lat: 30.25, distance: 2.5, icon: soldierIcon },
      { type: 'soldier', name: '李四', department: '消防队', lon: 107.971901, lat: 30.251428, distance: 2.3, icon: soldierIcon },
      { type: 'soldier', name: '王五', department: '医疗队', lon: 107.974901, lat: 30.241428, distance: 3.1, icon: soldierIcon },
      { type: 'soldier', name: '赵六', department: '应急救援队', lon: 108.047344, lat: 30.164313, distance: 4.2, icon: soldierIcon },
      { type: 'soldier', name: '刘七', department: '消防队', lon: 108.046344, lat: 30.168313, distance: 3.8, icon: soldierIcon },
      { type: 'soldier', name: '陈八', department: '医疗队', lon: 108.050344, lat: 30.170313, distance: 4.5, icon: soldierIcon },
      // 应急装备 (4个)
      { type: 'device', name: '救援车辆A', deviceType: '消防车', lon: 107.98088, lat: 30.2487, distance: 2.8, icon: deviceIcon },
      { type: 'device', name: '救援车辆B', deviceType: '救护车', lon: 107.97898, lat: 30.2502, distance: 2.6, icon: deviceIcon },
      { type: 'device', name: '无人机A', deviceType: 'DJI', lon: 108.049344, lat: 30.160313, distance: 4.8, icon: deviceIcon },
      { type: 'device', name: '无人机B', deviceType: 'DJI', lon: 108.043344, lat: 30.169313, distance: 3.6, icon: deviceIcon }
    ];

    simulatedPoints.forEach(point => {
      const entity = viewer.entities.add({
        position: Cesium.Cartesian3.fromDegrees(point.lon, point.lat, 0),
        billboard: {
          image: point.icon,
          width: 36,
          height: 40,
          verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
          heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
          disableDepthTestDistance: Number.POSITIVE_INFINITY,
        },
        properties: point.type === 'soldier'
          ? {
              type: 'soldier',
              name: point.name,
              department: point.department,
              location: `目前为止距离现场${point.distance}公里`
            }
          : {
              type: 'device',
              name: point.name,
              deviceType: point.deviceType,
              location: `目前为止距离现场${point.distance}公里`
            }
      });
    });

    console.log(`[index.vue] 已添加 ${simulatedPoints.length} 个模拟点位`);

    // camera.setView({
    //   ...DEFAULT_CAMERA_VIEW,
    // });
    camera.flyTo({
      ...DEFAULT_CAMERA_VIEW,
      duration: 1,
    });

    // 设置地图点击事件监听 - 显示 Tooltip
    setupMapClickHandler(viewer);

    // 延迟 1000ms 后设置相机到默认位置
    // setTimeout(() => {
    //   camera.flyTo({
    //     ...DEFAULT_CAMERA_VIEW,
    //     duration: 1,
    //   });
    // }, 5000);
    // return;

    /**
     * 设置相机到指定的笛卡尔坐标
     * @param {Cesium.Cartesian3 | null} cartesian - 目标位置
     * @returns {boolean} 是否成功设置
     */
    const focusCameraOnCartesian = (cartesian) => {
      if (!cartesian) return false;

      const cartographic = Cesium.Cartographic.fromCartesian(cartesian);
      const centerLon = Cesium.Math.toDegrees(cartographic.longitude);
      const centerLat = Cesium.Math.toDegrees(cartographic.latitude);

      console.log(
        `设置相机对准塌陷区域中心: 经度 ${centerLon.toFixed(
          6
        )}, 纬度 ${centerLat.toFixed(6)}`
      );

      camera.setView({
        ...DEFAULT_CAMERA_VIEW,
        lon: centerLon,
        lat: centerLat,
      });
      return true;
    };

    // 步骤1: 提前获取塌陷区域中心点（不依赖地形加载）
    // 如果成功获取，先设置相机对准该区域，让用户看到目标区域
    const collapseCenter = getCollapseCenter();
    let hasCameraTarget = focusCameraOnCartesian(collapseCenter);

    if (!hasCameraTarget) {
      console.warn("无法获取塌陷区域中心，使用默认相机位置");
      camera.setView(DEFAULT_CAMERA_VIEW);
    }

    // 步骤2: 加载3D Tiles（灾后场景）并等待完全就绪
    // 这一步至关重要，必须等待瓦片加载完成后才能准确采样地面高度
    try {
      console.log("[index.vue] 开始加载3D模型...");
      const afterTileset = await load3DTileset(viewer, "after", false);

      if (afterTileset) {
        console.log("[index.vue] 等待3D模型完全就绪（包括首批瓦片）...");
        await waitForTilesetReady(afterTileset);
        console.log("[index.vue] 3D模型已完全就绪");
      } else {
        console.warn("[index.vue] 3D模型加载返回 null");
      }
    } catch (error) {
      console.error("[index.vue] 3D模型加载失败:", error);
    }

    // 步骤3: 初始化地图标记（单兵、设备、应急基地等）
    // 此时3D Tiles已加载完成，可以安全添加标记
    try {
      console.log("[index.vue] 开始初始化地图标记...");
      const sampledCollapseCenter = await initializeMarkers(viewer, {
        useSampledHeights: true, // 使用采样高度，确保标记位置准确
        heightOffset: 100, // 标记相对地面100米（与 WuRenJi 保持一致）
      });

      // 如果之前没有设置相机（配置数据缺失），现在再次尝试
      if (!hasCameraTarget && sampledCollapseCenter) {
        hasCameraTarget = focusCameraOnCartesian(sampledCollapseCenter);
      }

      console.log("[index.vue] 地图标记初始化完成");
      // camera.setView({
      //   ...DEFAULT_CAMERA_VIEW,
      // })
    } catch (error) {
      console.error("[index.vue] 地图标记初始化失败:", error);
      // 即使标记初始化失败，也要确保相机位置正确
      if (!hasCameraTarget) {
        console.warn("[index.vue] 标记初始化失败且无相机目标，使用默认位置");
        // camera.setView(DEFAULT_CAMERA_VIEW)
      }
    }

    // 创建初始范围圈（使用当前搜索半径）
    createOrUpdateRangeCircle(viewer, disasterData.forcePreset.value.searchRadius);
  });
});

// 根据经纬度加载养护站数据 /disaster/matchEmergencyResources
const loadEmergencyResources = async (longitude, latitude) => {
  try {
    const response = await request({
      url: `/snow-ops-platform/disaster/matchEmergencyResources`,
      method: "GET",
      params: {
        longitude,
        latitude,
        maxDistance: disasterData.forcePreset.value.searchRadius,
      },
    });

    if (response?.data) {
      // 更新力量预置数据
      disasterData.updateForcePreset(response.data);
      console.log("[index.vue] 应急资源数据加载成功:", response.data);

      // 更新地图标记
      if (mapStore.viewer) {
        console.log("[index.vue] 更新地图应急资源标记...");

        // 清除旧的应急资源标记
        clearEmergencyResourceMarkers(mapStore.viewer);

        // 添加新的应急资源标记
        await addEmergencyResourceMarkers(
          mapStore.viewer,
          response.data,
          { longitude, latitude },
          { heightOffset: 10 }
        );
      } else {
        console.warn("[index.vue] 地图viewer未就绪，跳过标记更新");
      }
    } else {
      console.warn("[index.vue] 应急资源接口返回数据为空");
    }

    return response;
  } catch (error) {
    console.error("[index.vue] 加载应急资源数据失败:", error);
    ElMessage.warning({
      message: "应急资源数据加载失败,使用默认数据",
      duration: 3000,
    });
    return null;
  }
};

// 加载储备中心和预置点数据
const loadReserveCentersAndPresets = async (longitude, latitude) => {
  try {
    const response = await request({
      url: `/snow-ops-platform/yhYjll/list`,
      method: "GET",
      params: {
        longitude,
        latitude,
        maxDistance: disasterData.forcePreset.value.searchRadius,
      },
    });

    if (response?.data && Array.isArray(response.data)) {
      console.log("[index.vue] 储备中心和预置点数据加载成功:", response.data);

      // 更新地图标记
      if (mapStore.viewer) {
        console.log("[index.vue] 添加储备中心和预置点地图标记...");

        // 清除旧的标记
        clearReserveCenterMarkers(mapStore.viewer);

        // 添加新的标记
        await addReserveCenterMarkers(
          mapStore.viewer,
          response.data,
          { heightOffset: 10 }
        );
      } else {
        console.warn("[index.vue] 地图viewer未就绪，跳过标记更新");
      }
    } else {
      console.warn("[index.vue] 储备中心和预置点接口返回数据为空");
    }

    return response;
  } catch (error) {
    console.error("[index.vue] 加载储备中心和预置点数据失败:", error);
    ElMessage.warning({
      message: "储备中心和预置点数据加载失败",
      duration: 3000,
    });
    return null;
  }
};

onMounted(async () => {
  // 加载应急资源数据(使用默认灾害点坐标)
  // await loadEmergencyResources(108.011506, 30.175827);
  const response = await loadEmergencyResources(108.011506, 30.175827);

  // 加载储备中心和预置点数据(使用相同的坐标)
  await loadReserveCentersAndPresets(108.011506, 30.175827);
});

/**
 * 处理地图工具变化事件
 * 目前主要处理"模型对比"工具的切换
 *
 * @param {Object} payload - 工具变化事件载荷
 * @param {string} payload.tool - 工具标识
 * @param {boolean} payload.active - 工具是否激活
 */
const handleMapToolChange = async ({ tool, active }) => {
  console.log(`地图工具变化: ${tool}, 激活状态: ${active}`);

  if (tool === "modelCompare") {
    try {
      // 显示加载提示
      const loadingMessage = ElMessage({
        message: active ? "正在启用模型对比..." : "正在关闭模型对比...",
        type: "info",
        duration: 0,
        showClose: false,
      });

      // 使用新的双地图对比模式
      await toggleCompareMode(active, mapStore.viewer);

      // 关闭加载提示
      loadingMessage.close();

      // 显示成功提示
      ElMessage.success(active ? "模型对比已启用" : "模型对比已关闭");
    } catch (error) {
      console.error("切换模型对比模式失败:", error);

      // 显示错误提示
      ElMessage.error({
        message: `切换模型对比失败: ${error.message || "未知错误"}`,
        duration: 3000,
      });
    }
  }

  // 其他工具的处理可以在这里扩展
  // if (tool === 'measure') { ... }
};

// 弹窗状态
const showPersonnelDetail = ref(false);
const showCenterDetail = ref(false);

// 选中的数据
const selectedPersonnel = ref({
  name: "张强",
  department: "安全生产部",
  distance: 0.6,
  estimatedArrival: 10,
  avatar: null,
});

const selectedCenter = ref({
  name: "忠县应急中心",
  adminLevel: "国道",
  department: "交通公路部门",
  distance: 0.6,
  image: null,
});

// 返回驾驶舱
const handleBack = () => {
  console.log("返回驾驶舱");
  // 实际实现：路由跳转
  // router.push('/cockpit')
};

// 处理人员联动
const handlePersonnelLink = (personnel) => {
  console.log("联动人员:", personnel);
  // 实际实现：使用 mapStore 的 camera service 飞行到人员位置
  // const { camera } = mapStore.services()
  // camera.flyTo({ destination: [lon, lat, height] })
  showPersonnelDetail.value = false;
};

/**
 * 关闭地图 Tooltip
 * 统一的关闭入口，便于后续扩展埋点或联动逻辑
 */
const handleMapTooltipClose = () => {
  mapTooltip.value.visible = false;
};

/**
 * 处理力量调度启动事件
 * 显示加载动画，3秒后自动隐藏
 */
const handleStartDispatch = (payload) => {
  console.log('[index.vue] 启动力量调度:', payload);

  // 显示加载动画
  showLoading.value = true;

  // 3秒后自动隐藏加载动画
  setTimeout(() => {
    showLoading.value = false;
  }, 3000);
};

/**
 * 创建或更新范围圈
 * @param {Cesium.Viewer} viewer - Cesium viewer 实例
 * @param {number} radiusKm - 半径（公里）
 */
const createOrUpdateRangeCircle = (viewer, radiusKm) => {
  if (!viewer) return;

  const centerLon = 108.011506;
  const centerLat = 30.175827;
  const radiusMeters = radiusKm * 1000;

  // 如果已存在范围圈，先移除
  if (rangeCircleEntity.value) {
    viewer.entities.remove(rangeCircleEntity.value);
    rangeCircleEntity.value = null;
  }

  // 创建新的范围圈
  rangeCircleEntity.value = viewer.entities.add({
    position: Cesium.Cartesian3.fromDegrees(centerLon, centerLat, 0),
    ellipse: {
      semiMinorAxis: radiusMeters,
      semiMajorAxis: radiusMeters,
      height: 0,
      material: Cesium.Color.fromCssColorString('#1CA1FF').withAlpha(0.2),
      outline: true,
      outlineColor: Cesium.Color.fromCssColorString('#1CA1FF').withAlpha(0.8),
      outlineWidth: 2,
      heightReference: Cesium.HeightReference.CLAMP_TO_GROUND
    }
  });

  // 禁用范围圈的鼠标交互，让点击可以穿透到下面的标记点
  if (rangeCircleEntity.value) {
    rangeCircleEntity.value.allowPicking = false;
  }

  console.log(`[index.vue] 已创建/更新范围圈: ${radiusKm}km`);
};

/**
 * 在指定屏幕坐标显示地图 Tooltip
 *
 * 使用场景：
 * - 当用户点击地图上的标记点时调用此方法
 * - 调用方需要将地图实体的经纬度转换为屏幕坐标
 *
 * @typedef {Object} MapTooltipField
 * @property {string} label - 字段标签
 * @property {string} value - 字段值
 *
 * @typedef {Object} MapTooltipData
 * @property {MapTooltipField[]} fields - 字段列表
 *
 * @param {Object} options - Tooltip 配置选项
 * @param {number} options.x - 屏幕 X 坐标（像素），相对于地图容器左上角
 * @param {number} options.y - 屏幕 Y 坐标（像素），相对于地图容器左上角
 * @param {string} [options.title=''] - Tooltip 标题文本
 * @param {string} [options.icon=''] - 标题左侧图标的图片路径
 * @param {MapTooltipData} [options.data=null] - 业务数据，用于内容插槽渲染
 *
 * @example
 * // 当点击地图实体时
 * const screenPos = mapStore.worldToScreen(entity.position)
 * showMapTooltip({
 *   x: screenPos.x,
 *   y: screenPos.y,
 *   title: '应急中心',
 *   icon: emergencyCenterIcon,
 *   data: {
 *     fields: [
 *       { label: '名称', value: '忠县应急中心' },
 *       { label: '行政等级', value: '国道' },
 *       { label: '隶属单位', value: '交通公路部门' }
 *     ]
 *   }
 * })
 */
const showMapTooltip = ({ x, y, title = "", icon = "", data = null }) => {
  const state = mapTooltip.value;
  state.visible = true;
  state.x = x;
  state.y = y;
  state.title = title;
  state.icon = icon;
  state.data = data;
  // zIndex 保持不变，无需重新赋值
};

// TODO: 实现地图实体点击事件监听
// 当用户点击地图上的标记点时，显示 Tooltip 或详情弹窗
//
// 集成示例（需要先在文件顶部导入图标）：
// import personnelIcon from './assets/images/personnel-icon.png'
// import centerIcon from './assets/images/center-icon.png'
//
// mapStore.onReady(() => {
//   const { query } = mapStore.services()
//
//   // 监听实体点击事件
//   query.onEntityClick((entity) => {
//     // 1. 将实体位置转换为屏幕坐标
//     // 注意：具体 API 取决于你使用的地图引擎（Cesium/Mapbox/etc.）
//     const screenPos = mapStore.worldToScreen(entity.position)
//
//     // 2. 显示 Tooltip 展示基本信息
//     if (entity.type === 'personnel') {
//       showMapTooltip({
//         x: screenPos.x,
//         y: screenPos.y,
//         title: '应急人员',
//         icon: personnelIcon,
//         data: {
//           fields: [
//             { label: '姓名', value: entity.properties.name },
//             { label: '部门', value: entity.properties.department },
//             { label: '距离', value: `${entity.properties.distance}公里` }
//           ]
//         }
//       })
//     } else if (entity.type === 'center') {
//       showMapTooltip({
//         x: screenPos.x,
//         y: screenPos.y,
//         title: '应急中心',
//         icon: centerIcon,
//         data: {
//           fields: [
//             { label: '名称', value: entity.properties.name },
//             { label: '行政等级', value: entity.properties.adminLevel },
//             { label: '隶属单位', value: entity.properties.department }
//           ]
//         }
//       })
//     }
//
//     // 3. 如果需要打开详情弹窗，可以在 Tooltip 中添加按钮
//     // 或者直接在这里同时打开详情弹窗（根据业务需求）
//     // selectedPersonnel.value = entity.properties
//     // showPersonnelDetail.value = true
//   })
// })
</script>

<style scoped lang="scss">
@use "@/styles/mixins.scss" as *;
@use "./assets/styles/common.scss" as *;

.situational-awareness {
  // 容器查询设置，用于嵌入场景的自适应缩放
  container-name: situational-awareness;
  container-type: size;

  // 为旧版浏览器提供视口单位回退，封顶 1920×1080
  --cq-inline-100: clamp(0px, 100vw, 1920px);
  --cq-block-100: clamp(0px, 100vh, 1080px);

  // 当支持容器单位时覆盖为容器单位，同样封顶
  @supports (width: 1cqw) {
    --cq-inline-100: min(100cqw, 1920px);
  }
  @supports (height: 1cqh) {
    --cq-block-100: min(100cqh, 1080px);
  }

  // 可配置的布局变量（使用 calc 直接计算，避免函数嵌套）
  --sa-left-width: calc(464 / 1920 * var(--cq-inline-100, 100vw));
  --sa-right-width: calc(486 / 1920 * var(--cq-inline-100, 100vw));
  --sa-gap: calc(16 / 1920 * var(--cq-inline-100, 100vw));
  --sa-padding: calc(16 / 1920 * var(--cq-inline-100, 100vw));
  --sa-header-height: calc(
    131 / 1080 * var(--cq-block-100, 100vh)
  ); // Header 高度
  --sa-min-width: 1280px;
  --sa-min-height: 720px;

  position: relative;
  width: 100%;
  height: 100%;
  // max-width: 1920px;
  // max-height: 1080px;
  min-width: var(--sa-min-width);
  min-height: var(--sa-min-height);
  background-color: var(--bg-dark);
  overflow-x: hidden;
  overflow-y: auto; // 当宿主尺寸 < 最小尺寸时允许滚动，达到上限时不放大

  // PageHeader 浮在顶部
  > :first-child {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    z-index: 10;
  }

  &__main {
    position: absolute;
    inset: 0; // 铺满整个容器
    background: url(./assets/images/main-bg.png) center/cover no-repeat;
    overflow: hidden;
  }

  // 地图底层 - 填满整个容器
  &__map-layer {
    position: absolute;
    inset: 0;
    z-index: 0;
    display: flex;

    // 默认单地图模式
    &:not(.is-compare-mode) {
      .situational-awareness__right-map {
        width: 100%;
      }

      .situational-awareness__left-map {
        width: 0;
        opacity: 0;
        pointer-events: none;
        overflow: hidden;
      }
    }

    // 双地图对比模式
    &.is-compare-mode {
      .situational-awareness__left-map {
        width: 50%;
        opacity: 1;
        pointer-events: auto;
        transition: width 0.3s ease, opacity 0.3s ease;
      }

      .situational-awareness__right-map {
        width: 50%;
        transition: width 0.3s ease;
      }
    }
  }

  // 左侧地图容器（灾前场景 - 对比时显示）
  &__left-map {
    position: relative;
    height: 100%;
    background: #000;
  }

  // 右侧地图容器（灾后场景 - 主地图）
  &__right-map {
    position: relative;
    height: 100%;
  }

  // 中间分割线
  &__center-divider {
    position: absolute;
    left: 50%;
    top: 0;
    bottom: 0;
    width: 2px;
    background: linear-gradient(
      to bottom,
      rgba(255, 255, 255, 0.1),
      rgba(255, 255, 255, 0.5),
      rgba(255, 255, 255, 0.1)
    );
    z-index: 1;
    pointer-events: none;
  }

  // 地图遮罩层 - 覆盖在地图之上，增强视觉效果
  &__map-mask {
    position: absolute;
    inset: 0;
    z-index: 1;
    pointer-events: none; // 不阻挡交互
    // 使用 cockpit 的遮罩层图片，保持视觉一致性
    background: url(@/views/cockpit/assets/img/遮罩层.png) center/cover
      no-repeat;
  }

  // 场景标签层 - 显示在遮罩层和面板层之上
  &__scene-labels-layer {
    position: absolute;
    inset: 0;
    z-index: 10;
    pointer-events: none; // 标签不阻挡交互
  }

  // 浮动面板层 - 使用绝对定位固定面板位置
  &__panels-layer {
    position: absolute;
    inset: 0;
    z-index: 2;
    height: 100%;
    pointer-events: none; // 容器不拦截事件，让中间区域透明
  }

  // 左右面板列 - 浮动卡片样式
  &__panel-column {
    position: absolute;
    // top: var(--sa-header-height); // 从 header 下方开始
    // bottom: 0;
    display: flex;
    flex-direction: column;
    gap: var(--sa-gap); // 列内子面板之间的间距
    min-width: 0; // 防止在窄容器中溢出
    min-height: 0; // 允许 flex 子元素收缩并启用滚动
    pointer-events: auto; // 恢复面板的交互能力

    // 左侧面板固定在左边
    &--left {
      left: 0;
      width: var(--sa-left-width);
    }

    // 右侧面板固定在右边
    &--right {
      right: 0;
      width: var(--sa-right-width);
    }
  }

  // 中间占位区域 - 透明且不可交互，点击穿透到地图
  &__center-spacer {
    pointer-events: none;
  }

  // 折叠按钮层 - 独立层级，放置在屏幕两侧
  &__collapse-buttons-layer {
    position: absolute;
    inset: 0;
    z-index: 11; // 高于场景标签层
    pointer-events: none; // 容器不拦截事件
    padding-top: var(--sa-header-height); // 预留 Header 高度
  }

  // 折叠按钮
  &__collapse-btn {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    background: transparent;
    border: none;
    cursor: pointer;
    pointer-events: auto;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: all 0.3s ease;
    z-index: 11;
    padding: 0;

    &:hover {
      opacity: 0.8;
    }

    &:active {
      transform: translateY(-50%) scale(0.95);
    }

    .collapse-arrow {
      width: vw(30);
      height: auto;
      transition: all 0.3s ease;
    }

    // 左侧按钮 - 固定在屏幕最左侧
    &--left {
      left: 0;
    }

    // 右侧按钮 - 固定在屏幕最右侧
    &--right {
      right: 0;
    }
  }

  // 面板滑动动画 - 左侧
  .panel-slide-left-enter-active,
  .panel-slide-left-leave-active {
    transition: all 0.3s ease;
  }

  .panel-slide-left-enter-from {
    transform: translateX(-100%);
    opacity: 0;
  }

  .panel-slide-left-leave-to {
    transform: translateX(-100%);
    opacity: 0;
  }

  // 面板滑动动画 - 右侧
  .panel-slide-right-enter-active,
  .panel-slide-right-leave-active {
    transition: all 0.3s ease;
  }

  .panel-slide-right-enter-from {
    transform: translateX(100%);
    opacity: 0;
  }

  .panel-slide-right-leave-to {
    transform: translateX(100%);
    opacity: 0;
  }

  // 地图控件层 - 高于遮罩和面板，用于放置地图控制工具
  &__controls-layer {
    position: absolute;
    inset: 0;
    z-index: 3;
    pointer-events: none; // 容器不拦截事件
    display: flex;
    justify-content: center;
    align-items: flex-end;
    padding-bottom: 30px; // 临时使用固定值，确保控件显示
  }

  // 控件容器 - 恢复交互能力
  &__controls {
    pointer-events: auto;
    position: relative;
    // 调试：确保控件容器可见
    min-height: 56px; // MapControls 的高度
  }

  // 地图 Tooltip 层 - 覆盖地图和面板，仅 Tooltip 自身可交互
  &__tooltip-layer {
    position: absolute;
    inset: 0;
    z-index: 4; // 高于控件层
    pointer-events: none; // 容器不拦截事件，点击穿透到地图
  }

  // 加载动画层 - 一键启动后显示
  &__loading-layer {
    position: absolute;
    top: calc(var(--sa-header-height) + vh(40));
    left: 0;
    right: 0;
    // bottom: 0;
    z-index: 5; // 高于 Tooltip 层
    display: flex;
    align-items: center;
    justify-content: center;
    pointer-events: none; // 不阻止点击穿透
  }

  // 加载 GIF 图片
  &__loading-gif {
    width: auto;
    height: auto;
    max-width: 80%;
    max-height: 60%;
    object-fit: contain;
  }
}

// Tooltip 内容字段样式
// 用于在 Tooltip 插槽中展示字段列表
.tooltip-field-item {
  display: flex;
  align-items: baseline;
  gap: vw(8);
  padding: vh(6) 0;

  .tooltip-field-label {
    color: var(--text-gray);
    font-size: fs(13);
    font-family: SourceHanSansCN-Regular, sans-serif;
    white-space: nowrap;
    flex-shrink: 0;
  }

  .tooltip-field-value {
    color: var(--text-white);
    font-size: fs(13);
    font-family: SourceHanSansCN-Medium, sans-serif;
    font-weight: 500;
    flex: 1;
    word-break: break-all;
  }
}

// 窄容器嵌入的紧凑布局（<1100px 宽度）
.situational-awareness.is-compact {
  --sa-left-width: calc(380 / 1920 * var(--cq-inline-100, 100vw));
  --sa-right-width: calc(400 / 1920 * var(--cq-inline-100, 100vw));
  --sa-gap: calc(12 / 1920 * var(--cq-inline-100, 100vw));
  --sa-padding: calc(12 / 1920 * var(--cq-inline-100, 100vw));
}

// 嵌入模式 - 使用更保守的最小尺寸
.situational-awareness.is-embedded {
  --sa-min-width: 1024px;
  --sa-min-height: 600px;
}
</style>
