<template>
  <div class="edit-page">
    <!-- 地图容器 -->
    <div class="map-container">
      <!-- 左侧工具栏 -->
      <div class="toolbar-container">
        <MapToolbar
          preset="edit"
          :selected-key="currentMode"
          @mode-change="handleModeChange"
          @zoom-in="handleZoomIn"
          @zoom-out="handleZoomOut"
          @center-robot="handleCenterRobot"
          @toggle-fullscreen="handleToggleFullscreen"
          @save="handleSaveMap"
        />
						</div>

      <!-- 地图组件（作为主内容区域） -->
      <div id="map-stage" class="page-content" ref="mapContent">
        <OlMap 
          ref="olmap" 
          :width="olWidth + 'px'" 
          :height="olHeight + 'px'" 
          backgroundColor="#F5F5F5" 
          :mapName="mapName"
					:robotPoseData="robotPoseData"
          :pointDraSelectEnabled="pointDraSelectEnabled"
          :showDefaultControls="false"
          @elementRoadInitEnd="elementRoadInitEnd"
          @elementRoadDrawEnd="elementRoadDrawEnd"
          @removeElementResult="removeElementResult"
          @selectShowEleResult="selectShowEleResult"
        />
        
        <!-- 底部Inspector面板 -->
        <BottomInspector
          ref="bottomInspector"
          :visible="inspector.visible"
          :mode="inspector.mode"
          :data="inspector.data"
          :loading="inspector.loading"
          @edit="handleInspectorEdit"
          @save="handleInspectorSave"
          @cancel="handleInspectorCancel"
          @close="handleInspectorClose"
          @locate="handleInspectorLocate"
          @height-change="handleInspectorHeightChange"
        />
					</div>

      <!-- 右侧面板 -->
      <div class="panel-container">
        <RightPanel
          mode="edit"
          panelType="edit"
          v-model="rightPanelVisible"
          :overlay="true"
          :tabs="rightPanelTabs"
          :initial-tab="'info'"
          :realtime-info="realtimeInfo"
          :element-list="allElementList"
          :selected-element="currentFeature"
          :element-types="elementTypeCounts"
          @add-current-point="handleAddCurrentPoint"
          @element-select="handleElementSelect"
          @element-edit="handleElementEdit"
          @element-locate="handleElementLocate"
          @element-remove="handleElementRemove"
          @network-export="handleNetworkExport"
          @network-import="handleNetworkImport"
        />
					</div>
					</div>

    <!-- 添加当前点对话框 -->
    <el-dialog 
      title="添加当前实时位姿点" 
      :visible.sync="addCurrentMapShow" 
      width="480px" 
      @open="openCurrentToMapDialog"
      class="add-pose-dialog"
      :close-on-click-modal="false"
      :modal="true"
      :modal-append-to-body="true"
      :append-to-body="true"
      center
      custom-class="centered-dialog"
    >
      <div class="dialog-content">
        <el-form ref="currentPointForm" :model="currentRobotRecord" label-width="90px" size="small" class="pose-form">
          <div class="form-section">
            <h4 class="section-title">
              <i class="el-icon-location-outline"></i>
              位置信息
            </h4>
            <el-form-item label="X坐标(m)" prop="x">
              <el-input-number 
                v-model="currentRobotRecord.x" 
                :precision="3"
                :step="0.1"
                controls-position="right"
                placeholder="请输入X坐标值"
                class="coordinate-input"
                style="width: 100%;"
              />
            </el-form-item>
            <el-form-item label="Y坐标(m)" prop="y">
              <el-input-number 
                v-model="currentRobotRecord.y" 
                :precision="3"
                :step="0.1"
                controls-position="right"
                placeholder="请输入Y坐标值"
                class="coordinate-input"
                style="width: 100%;"
              />
            </el-form-item>
            <el-form-item label="Z坐标(m)" prop="z">
              <el-input-number 
                v-model="currentRobotRecord.z" 
                :precision="3"
                :step="0.1"
                controls-position="right"
                placeholder="请输入Z坐标值"
                class="coordinate-input"
                style="width: 100%;"
              />
            </el-form-item>
						</div>

          <div class="form-section">
            <h4 class="section-title">
              <i class="el-icon-guide"></i>
              方向配置
            </h4>
            <el-form-item label="航偏角(rad)" prop="angle">
              <el-input-number 
                v-model="currentRobotRecord.angle" 
                :precision="3"
                :step="0.1"
                controls-position="right"
                placeholder="请输入航偏角值"
                style="width: 100%;"
              />
						</el-form-item>
            <el-form-item label="航偏角使能" prop="angleEnable">
              <el-switch v-model="currentRobotRecord.angleEnable" />
						</el-form-item>
          </div>
			</el-form>
      </div>
			<span slot="footer" class="dialog-footer">
        <el-button @click="addCurrentMapShow = false" size="medium">取 消</el-button>
        <el-button type="primary" @click="addCurrentToMap" size="medium">
          <i class="el-icon-check"></i> 确 定
        </el-button>
			</span>
		</el-dialog>
		<MqttComp ref="mqtt" :topics="topics" @message-received="onMessage" />
	</div>
</template>

<script>
import axios from "axios";
import OlMap from "@/components/OlMap"
import MapToolbar from "./components/shared/MapToolbar.vue"
import RightPanel from "./components/shared/RightPanel.vue"
import BottomInspector from "@/components/BottomInspector.vue"
import MqttComp from "@/components/Mqtt/mqttComp.vue"
import { saveRoadMapGeoJson, getRoadMapGeoJson } from "@/api/map/index"
export default {
	name: "EditPage",
	components: {
		OlMap,
		MapToolbar,
		RightPanel,
		BottomInspector,
		MqttComp
	},
	data() {
		return {
			topics:[
				{ topic:this.$mqttPrefix + '/localization/pose'},
				{ topic: this.$mqttPrefix + '/sensor/battery'},
			],
			// 地图相关
		olWidth: 0,
		olHeight: 0,
		mapName: this.$route.query.mapName || '',
			
			// 编辑模式相关
			currentMode: 'select', // 当前编辑模式
			pointDraSelectEnabled: true, // 元素选择模式是否启用
			
			// 面板显示控制
			rightPanelVisible: true,
			
			// Inspector状态管理
			inspector: {
			visible: false,
				mode: 'view', // 'view' | 'edit'
				data: null,
				loading: false
			},
			
			// 右侧面板配置
			rightPanelTabs: ['info', 'elements', 'network'],
			
		// 实时信息数据
		realtimeInfo: {
			currentMap: this.$route.query.mapName || 'Unknown',
				currentTask: '地图编辑',
				speed: '0m/s',
				speedCommand: '0m/s',
				coordinates: '(0, 0, 0)',
				heading: '0°',
				totalDistance: '0m',
				registrationError: '0',
				batteryLevel: '0%'
			},
			
			// 元素数据
			pointData: [],
			lineData: [],
			bowData: [],
			shapeData: [],
			resourcesFeature: [], // 所有元素的原始Feature对象
			currentFeature: {}, // 当前选中的元素
			
			// 添加当前点对话框
			addCurrentMapShow: false,
			currentRobotRecord: {
				x: 0,
				y: 0,
				z: 0,
				angle: 0,
				angleEnable: false
			},
			
			// 机器人位姿数据
			robotPoseData: {
				x: 0,
				y: 0,
				angle: 0
			},
			
			// 页面状态
			haveDraw: false, // 是否有未保存的更改
		};
	},
	computed: {
		// 所有元素列表（用于右侧面板）
		allElementList() {
			return [
				...this.pointData,
				...this.lineData,
				...this.bowData,
				...this.shapeData
			];
		},
		
		// 元素类型统计
		elementTypeCounts() {
			return [
				{ key: 'point', label: '点', count: this.pointData.length },
				{ key: 'line', label: '线', count: this.lineData.length },
				{ key: 'curve', label: '弧', count: this.bowData.length },
				{ key: 'polygon', label: '面', count: this.shapeData.length }
			];
		}
	},
	watch: {
		// 监听右侧面板显隐变化
		rightPanelVisible(visible) {
			this.updateRightWidth(visible ? 380 : 0);
		}
	},
	created() {
		// 获取地图ID
		// this.mapName = this.$route.params.mapId || 'demo';
	},
	// Vue keep-alive激活时的钩子
	activated() {
		console.log('编辑页面被激活');
		// 使用$nextTick确保DOM完全渲染后再更新地图
		this.$nextTick(() => {
			// 重新计算地图容器尺寸
			this.updateMapSize();
			
			// 更新OpenLayers地图尺寸
			if (this.$refs.olmap && this.$refs.olmap.map) {
				// 延迟一下以确保容器尺寸已更新
				setTimeout(() => {
					this.$refs.olmap.map.updateSize();
					console.log('✅ 编辑页面地图尺寸已更新');
				}, 100);
			}
			
			// 如果地图组件有refresh方法，也调用一下
			if (this.$refs.olmap && this.$refs.olmap.refresh) {
				setTimeout(() => {
					this.$refs.olmap.refresh();
				}, 150);
			}
		});
	},
	
	beforeDestroy() {
		window.removeEventListener("beforeunload", this.handleBeforeUnload);
		window.removeEventListener('resize', this.updateMapSize);
	},
	beforeRouteLeave(to, from, next) {
		// 检查Inspector是否有未保存更改
		const inspectorHasChanges = this.inspector.visible && this.inspector.mode === 'edit' && this.$refs.bottomInspector?.hasUnsavedChanges;
		
		// 如果页面有修改或者新增删除,则拦截*前端路由跳转*, 二次确认
		if (this.haveDraw || inspectorHasChanges) {
			const message = inspectorHasChanges ? 
				'Inspector中有未保存的元素更改，确定要跳转或退出?' : 
				'当前页面的地图修改还未保存,确定要跳转或退出?';
				
			this.$confirm(message, '提示', {
			confirmButtonText: '确定',
			cancelButtonText: '取消',
			type: 'warning'
		}).then(() => {
				// 关闭Inspector
				if (this.inspector.visible) {
					this.inspector.visible = false;
				}
			next();
		}).catch(() => {
			next(false);
		});
		} else {
			next();
		}
	},
	mounted() {
		this.updateMapSize();
		this.initEditMode();
		this.updateRightWidth(this.rightPanelVisible ? 380 : 0);
		window.addEventListener('resize', this.updateMapSize);
		window.addEventListener("beforeunload", this.handleBeforeUnload);
	},
	methods: {
		// === 页面初始化相关 ===
		onMessage({ topic, message }) {
				if (topic === this.$mqttPrefix + '/localization/pose') {
						this.handlePoseMessage(message);
				}else if (topic === this.$mqttPrefix + '/sensor/battery') {
					// 处理电池消息
					const data = message.args[0];
					this.realtimeInfo.batteryLevel = (data.capacity * 100).toFixed(2) + '%' || '0%';
				}

		},
		handlePoseMessage(message) {
			try {
				const data = message.args[0];				
        const {xyz, rpy, blh, heading} = data.pose;
				this.robotPoseData.x = xyz[0];
				this.robotPoseData.y = xyz[1];
				this.robotPoseData.angle = rpy[2];
				this.currentRobotRecord.x = xyz[0];
				this.currentRobotRecord.y = xyz[1];
				this.currentRobotRecord.z = xyz[2];
				this.currentRobotRecord.angle = rpy[2];
				this.realtimeInfo.coordinates = `(${xyz[0]},${xyz[1]},${xyz[2]})`;
				this.realtimeInfo.heading = rpy[2] + '°'; // 航向角
				this.realtimeInfo.speed = data.vel.heading+ 'm/s'; // 速度
				this.realtimeInfo.speedCommand = data.vel.enu + 'm/s'; // 速度指令
				this.realtimeInfo.totalDistance = data.odometer + 'm'; // 总里程
				this.realtimeInfo.registrationError = data.score;
			} catch (error) {
				console.error('解析位姿消息失败:', error);
			}
		},
		// 更新地图尺寸
		updateMapSize() {
			const mapContent = this.$refs.mapContent;
			if (mapContent) {
				this.olWidth = mapContent.offsetWidth;
				this.olHeight = mapContent.offsetHeight;
			}
		},
		
		// 初始化编辑模式
		initEditMode() {
			this.currentMode = 'select-mode'; // 使用工具栏的key
			this.pointDraSelectEnabled = true;
			console.log('编辑模式初始化完成，当前模式:', this.currentMode);
		},
		
		// 处理页面刷新/关闭前的确认
		handleBeforeUnload(event) {
			if (this.haveDraw) {
				event.preventDefault();
				event.returnValue = "";
			}
		},
		
		// 更新右侧面板宽度变量
		updateRightWidth(width) {
			const host = this.$el || document.documentElement;
			host.style.setProperty('--right-panel-width', `${width}px`);
		},
		
		// === 工具栏事件处理 ===
		
		// 处理模式切换
		handleModeChange(mode) {
			// 将工具栏的key映射到内部模式
			const modeMap = {
				'select-mode': 'select',
				'draw-point': 'draw-point',
				'draw-line': 'draw-line',
				'draw-curve': 'draw-curve',
				'draw-polygon': 'draw-polygon'
			};
			
			const internalMode = modeMap[mode] || mode;
			this.currentMode = mode; // 保存工具栏的key用于选中状态
			
			// 根据模式切换地图交互状态
			switch (internalMode) {
				case 'select':
					this.pointDraSelectEnabled = true;
					this.$refs.olmap && this.$refs.olmap.clearDraw && this.$refs.olmap.clearDraw();
					this.$message.success('已切换到选择模式');
					break;
				case 'draw-point':
					this.pointDraSelectEnabled = false;
					if (this.$refs.olmap && this.$refs.olmap.drawPoint) {
						this.$refs.olmap.drawPoint();
						this.$message.success('已切换到绘点模式，点击地图添加点位');
					} else {
						this.$message.warning('地图组件未就绪，请稍后重试');
					}
					break;
				case 'draw-line':
					this.pointDraSelectEnabled = false;
					if (this.$refs.olmap && this.$refs.olmap.drawLine) {
						this.$refs.olmap.drawLine();
						this.$message.success('已切换到绘线模式，点击地图绘制线段');
					} else {
						this.$message.warning('地图组件未就绪，请稍后重试');
					}
					break;
				case 'draw-curve':
					this.pointDraSelectEnabled = false;
					if (this.$refs.olmap && this.$refs.olmap.drawCurve) {
						this.$refs.olmap.drawCurve();
						this.$message.success('已切换到绘曲线模式，点击地图绘制曲线');
					} else {
						this.$message.warning('地图组件未就绪，请稍后重试');
					}
					break;
				case 'draw-polygon':
					this.pointDraSelectEnabled = false;
					if (this.$refs.olmap && this.$refs.olmap.drawPolygon) {
						this.$refs.olmap.drawPolygon();
						this.$message.success('已切换到绘区域模式，点击地图绘制多边形区域');
					} else {
						this.$message.warning('地图组件未就绪，请稍后重试');
					}
					break;
				default:
					console.warn('未知的绘制模式:', mode);
					break;
			}
		},
		
		// 工具栏基础操作
		handleZoomIn() {
			// TODO: 实现地图放大
			this.$message.info('地图放大');
		},
		
		handleZoomOut() {
			// TODO: 实现地图缩小
			this.$message.info('地图缩小');
		},
		
		handleCenterRobot() {
			// TODO: 实现居中到机器人
			this.$message.info('居中到机器人');
		},
		
		handleToggleFullscreen() {
			// TODO: 实现全屏切换
			this.$message.info('全屏切换');
		},
		
		async handleSaveMap() {
			// 检查是否有未保存的更改
			if (!this.haveDraw && this.resourcesFeature.length > 0) {
				this.$message.info('当前没有需要保存的更改');
				return;
			}
			
			if (this.resourcesFeature.length === 0) {
				this.$message.warning('当前地图没有任何元素可保存');
				return;
			}
			
			try {
				this.$message.info('正在保存路网数据...');
				await this.saveRoute();
				// saveRoute方法内部已经有成功消息，这里不需要重复显示
			} catch (error) {
				// saveRoute方法内部已经有错误处理，这里不需要重复处理
				console.error('保存失败:', error);
			}
		},
		
		// === 右侧面板事件处理 ===
		
		// 添加当前点
		handleAddCurrentPoint() {
			this.addCurrentMapShow = true;
		},
		
		// 元素选择
		handleElementSelect(element) {
			this.showInspector(element, 'edit');
			// 在地图上选中该元素
			if (this.$refs.olmap && this.$refs.olmap.selectShowEle && element && element.id) {
				this.$refs.olmap.selectShowEle(element.id);
			}
		},
		
		
		// 编辑元素
		handleElementEdit(element) {
			// 先在地图上选中该元素，确保地图组件状态正确
			if (this.$refs.olmap && this.$refs.olmap.selectShowEle && element && element.id) {
				this.$refs.olmap.selectShowEle(element.id);
			}
			this.showInspector(element, 'edit');
		},
		
		// 定位元素
		handleElementLocate(element) {
			if (this.$refs.olmap && this.$refs.olmap.selectShowEle && element && element.id) {
				this.$refs.olmap.selectShowEle(element.id);
				this.$message.success(`已定位到元素 ${element.id}`);
			} else {
				this.$message.error('无法定位元素');
			}
		},
		
		// 删除元素
	async handleElementRemove(element) {
		try {
			await this.$confirm(`确定要删除元素 ${element.id} 吗？`, '确认删除', {
				confirmButtonText: '确定',
				cancelButtonText: '取消',
				type: 'warning'
			});

			// 显示删除进度
			const loading = this.$loading({
				lock: true,
				text: '正在删除元素...',
				spinner: 'el-icon-loading',
				background: 'rgba(0, 0, 0, 0.7)'
			});

			try {
				// 从地图组件中删除元素
				if (this.$refs.olmap && this.$refs.olmap.removeElement) {
					this.$refs.olmap.removeElement(element.id);
				}

				// 删除完成后自动保存到后端
				await this.saveRoute();
				
				// 如果底部 Inspector 正在显示被删除的元素，则关闭它
				if (this.inspector.visible && this.inspector.data && this.inspector.data.id === element.id) {
					this.inspector.visible = false;
					this.inspector.mode = 'view';
					this.inspector.data = null;
				}
				
				this.$message.success(`元素 ${element.id} 删除成功`);
			} finally {
				loading.close();
			}
		} catch (error) {
			if (error !== 'cancel') {
				console.error('删除元素失败:', error);
				this.$message.error('删除元素失败: ' + (error.message || '未知错误'));
			}
		}
	},
		
		// 路网导出
		async handleNetworkExport() {
			try {
				// 检查是否有路网数据可导出
				if (!this.resourcesFeature || this.resourcesFeature.length === 0) {
					this.$message.warning('当前地图没有路网数据可导出');
					return;
				}

				// 显示导出进度
				const loading = this.$loading({
					lock: true,
					text: '正在准备导出数据...',
					spinner: 'el-icon-loading',
					background: 'rgba(0, 0, 0, 0.7)'
				});

				try {
					// 构建导出的GeoJSON数据
					const geoJsonData = this.buildGeoJsonData();
					
					// 添加导出时间戳和元数据
					const exportData = {
						...geoJsonData,
						metadata: {
							exportTime: new Date().toISOString(),
							mapName: this.mapName,
							elementCount: geoJsonData.features.length,
							version: '1.0'
						}
					};

					// 创建文件内容
					const fileContent = JSON.stringify(exportData, null, 2);
					const blob = new Blob([fileContent], { type: 'application/json' });
					
					// 生成文件名
					const timestamp = new Date().toISOString().replace(/[:.]/g, '-').slice(0, 19);
					const fileName = `roadmap_${this.mapName}_${timestamp}.json`;
					
					// 创建下载链接
					const url = window.URL.createObjectURL(blob);
					const link = document.createElement('a');
					link.href = url;
					link.download = fileName;
					
					// 触发下载
					document.body.appendChild(link);
					link.click();
					document.body.removeChild(link);
					
					// 清理URL对象
					window.URL.revokeObjectURL(url);
					
					this.$message.success(`路网数据已导出：${fileName}`);
				} finally {
					loading.close();
				}
			} catch (error) {
				console.error('路网导出失败:', error);
				this.$message.error('路网导出失败：' + (error.message || '未知错误'));
			}
		},
		
		// 路网导入
		handleNetworkImport(type) {
			const typeMap = {
				'import': '导入',
				'replace': '覆盖导入',
				'merge': '合并导入',
				'incremental': '增量导入'
			};
			
			// 创建文件输入元素
			const fileInput = document.createElement('input');
			fileInput.type = 'file';
			fileInput.accept = '.json';
			fileInput.style.display = 'none';
			
			// 文件选择处理
			fileInput.addEventListener('change', async (event) => {
				const file = event.target.files[0];
				if (!file) return;
				
				try {
					await this.processImportFile(file, type, typeMap[type] || '导入');
				} catch (error) {
					console.error('导入处理失败:', error);
					this.$message.error(`路网${typeMap[type] || '导入'}失败：` + (error.message || '未知错误'));
				} finally {
					// 清理文件输入元素
					document.body.removeChild(fileInput);
				}
			});
			
			// 添加到页面并触发点击
			document.body.appendChild(fileInput);
			fileInput.click();
		},

		// 处理导入文件
		async processImportFile(file, importType, typeName) {
			// 显示加载进度
			const loading = this.$loading({
				lock: true,
				text: `正在${typeName}路网数据...`,
				spinner: 'el-icon-loading',
				background: 'rgba(0, 0, 0, 0.7)'
			});

			try {
				// 读取文件内容
				const fileContent = await this.readFileContent(file);
				
				// 解析JSON数据
				let importData;
				try {
					importData = JSON.parse(fileContent);
				} catch (parseError) {
					throw new Error('文件格式错误：无法解析JSON数据');
				}

				// 验证数据格式
				this.validateImportData(importData);

				// 根据不同导入类型执行相应策略
				await this.executeImportStrategy(importData, importType);

				// 刷新地图显示
				await this.refreshMapAfterImport();

				// 保存到服务器
				await this.saveRoute();

				this.$message.success(`路网${typeName}成功！共处理${importData.features.length}个元素`);
			} finally {
				loading.close();
			}
		},

		// 读取文件内容
		readFileContent(file) {
			return new Promise((resolve, reject) => {
				const reader = new FileReader();
				reader.onload = e => resolve(e.target.result);
				reader.onerror = () => reject(new Error('文件读取失败'));
				reader.readAsText(file);
			});
		},

		// 验证导入数据格式
		validateImportData(data) {
			// 检查基本结构
			if (!data || typeof data !== 'object') {
				throw new Error('无效的数据格式');
			}

			if (data.type !== 'FeatureCollection') {
				throw new Error('数据类型错误：期望FeatureCollection格式');
			}

			if (!Array.isArray(data.features)) {
				throw new Error('数据格式错误：缺少features数组');
			}

			if (data.features.length === 0) {
				throw new Error('导入文件中没有路网元素');
			}

			// 验证每个feature的格式
			data.features.forEach((feature, index) => {
				if (!feature.type || feature.type !== 'Feature') {
					throw new Error(`第${index + 1}个元素格式错误：不是有效的Feature`);
				}

				if (!feature.properties || !feature.properties.id) {
					throw new Error(`第${index + 1}个元素缺少ID属性`);
				}

				if (!feature.geometry || !feature.geometry.type) {
					throw new Error(`第${index + 1}个元素缺少几何信息`);
				}
			});
		},

		// 执行不同的导入策略
		async executeImportStrategy(importData, importType) {
			const features = importData.features;

			switch (importType) {
				case 'replace':
					// 覆盖导入：清空现有数据，导入新数据
					await this.replaceImport(features);
					break;
				case 'merge':
					// 合并导入：保留现有数据，添加新数据（处理ID冲突）
					await this.mergeImport(features);
					break;
				case 'incremental':
					// 增量导入：只导入不存在的新元素
					await this.incrementalImport(features);
					break;
				default:
					// 普通导入：直接添加到现有数据
					await this.normalImport(features);
					break;
			}
		},

		// 覆盖导入
		async replaceImport(features) {
			// 清空现有数据
			this.clearAllMapElements();
			
			// 导入新数据
			await this.importFeaturesToMap(features);
		},

		// 合并导入
		async mergeImport(features) {
			const conflictFeatures = [];
			const newFeatures = [];

			// 检查ID冲突
			features.forEach(feature => {
				const existingFeature = this.resourcesFeature.find(f => f.getId() === feature.properties.id);
				if (existingFeature) {
					conflictFeatures.push(feature);
				} else {
					newFeatures.push(feature);
				}
			});

			// 处理冲突
			if (conflictFeatures.length > 0) {
				const conflictIds = conflictFeatures.map(f => f.properties.id).join(', ');
				const result = await this.$confirm(
					`发现${conflictFeatures.length}个ID冲突的元素：${conflictIds}。是否覆盖现有元素？`,
					'ID冲突处理',
					{
						confirmButtonText: '覆盖现有',
						cancelButtonText: '跳过冲突',
						type: 'warning'
					}
				);

				if (result) {
					// 覆盖冲突的元素
					await this.replaceConflictFeatures(conflictFeatures);
				}
			}

			// 导入新元素
			if (newFeatures.length > 0) {
				await this.importFeaturesToMap(newFeatures);
			}
		},

		// 增量导入
		async incrementalImport(features) {
			const newFeatures = features.filter(feature => {
				return !this.resourcesFeature.find(f => f.getId() === feature.properties.id);
			});

			if (newFeatures.length === 0) {
				this.$message.info('所有元素均已存在，无需导入');
				return;
			}

			await this.importFeaturesToMap(newFeatures);
			this.$message.info(`跳过${features.length - newFeatures.length}个已存在的元素`);
		},

		// 普通导入
		async normalImport(features) {
			await this.importFeaturesToMap(features);
		},

		// 清空所有地图元素
		clearAllMapElements() {
			if (this.$refs.olmap && this.$refs.olmap.clearAllElements) {
				this.$refs.olmap.clearAllElements();
			}
			
			// 清空数据数组
			this.pointData = [];
			this.lineData = [];
			this.bowData = [];
			this.shapeData = [];
			this.resourcesFeature = [];
			this.currentFeature = {};
		},

		// 替换冲突的特征
		async replaceConflictFeatures(conflictFeatures) {
			for (const feature of conflictFeatures) {
				// 删除现有元素
				if (this.$refs.olmap && this.$refs.olmap.removeElement) {
					this.$refs.olmap.removeElement(feature.properties.id);
				}
				
				// 从数据数组中删除
				this.removeFeatureFromArrays(feature.properties.id);
			}
			
			// 导入新的特征
			await this.importFeaturesToMap(conflictFeatures);
		},

		// 从数据数组中删除特征
		removeFeatureFromArrays(id) {
			const removeFromArray = (array) => {
				const index = array.findIndex(item => item.id === id);
				if (index !== -1) {
					array.splice(index, 1);
				}
			};

			if (id.startsWith('p')) {
				removeFromArray(this.pointData);
			} else if (id.startsWith('l')) {
				removeFromArray(this.lineData);
			} else if (id.startsWith('b')) {
				removeFromArray(this.bowData);
			} else if (id.startsWith('s')) {
				removeFromArray(this.shapeData);
			}

			// 从resourcesFeature中删除
			const index = this.resourcesFeature.findIndex(f => f.getId() === id);
			if (index !== -1) {
				this.resourcesFeature.splice(index, 1);
			}
		},

		// 将特征导入到地图
		async importFeaturesToMap(features) {
			if (!this.$refs.olmap || !this.$refs.olmap.importGeoJsonFeatures) {
				throw new Error('地图组件未就绪，无法导入数据');
			}

			// 调用地图组件的导入方法
			const geoJsonData = {
				type: 'FeatureCollection',
				features: features
			};

			await this.$refs.olmap.importGeoJsonFeatures(geoJsonData);
		},

		// 导入后刷新地图
		async refreshMapAfterImport() {
			// 等待地图组件处理完成
			await this.$nextTick();
			
			// 如果地图组件有刷新方法，调用它
			if (this.$refs.olmap && this.$refs.olmap.refresh) {
				this.$refs.olmap.refresh();
			}
		},
		
		// === Inspector事件处理 ===
		
		// 显示Inspector
		showInspector(element, mode = 'edit') {
			this.inspector.loading = true;
			this.inspector.visible = true;
			this.inspector.mode = mode;
			
			// 模拟数据加载延迟
			setTimeout(() => {
				// 准备元素数据
				const elementData = this.prepareElementData(element);
				this.inspector.data = elementData;
				this.inspector.loading = false;
				this.currentFeature = element;
			}, 100);
		},
		
		// 准备元素数据
		prepareElementData(element) {
			// 从resourcesFeature中获取完整的元素数据
			const feature = this.resourcesFeature.find(f => f.getId() === element.id);
			if (feature) {
				const properties = feature.getProperties();
				const geometry = feature.getGeometry();
				
				// 合并基础信息和属性
				return {
					...element,
					...properties,
					type: geometry.getType(),
					position: geometry.getType() === 'Point' ? geometry.getCoordinates() : undefined
				};
			}
			return element;
		},
		
		// Inspector编辑模式
		handleInspectorEdit() {
			this.inspector.mode = 'edit';
		},
		
		// Inspector保存
		async handleInspectorSave(elementData) {
			// 保存前验证数据
			if (!elementData || !elementData.id) {
				this.$message.error('保存失败：元素数据无效');
				return;
			}
			
			// 保存前检查resourcesFeature数组
			if (!this.resourcesFeature || this.resourcesFeature.length === 0) {
				this.$message.error('保存失败：找不到地图元素数据');
				return;
			}
			
			console.log('保存前元素数量:', this.resourcesFeature.length);
			console.log('保存前元素列表:', this.resourcesFeature.map(f => f.getId()));
			
			// 显示保存进度
			const loading = this.$loading({
				lock: true,
				text: '正在保存元素...',
				spinner: 'el-icon-loading',
				background: 'rgba(0, 0, 0, 0.7)'
			});
			
			try {
				// 查找要更新的元素
				let targetFeature = null;
				for (let i = 0; i < this.resourcesFeature.length; i++) {
					if (this.resourcesFeature[i].getId() === elementData.id) {
						targetFeature = this.resourcesFeature[i];
						break;
					}
				}
				
				if (!targetFeature) {
					throw new Error(`找不到ID为 ${elementData.id} 的元素`);
				}
				
				// 创建元素数据的副本以避免直接修改
				const cleanData = { ...elementData };
				delete cleanData.typeEle;
				delete cleanData.directList;
				
				// 更新元素属性
				targetFeature.setProperties(cleanData);
				
				// 特殊处理：更新坐标
				if (elementData.position && targetFeature.getGeometry().getType() === 'Point') {
					targetFeature.getGeometry().setCoordinates(elementData.position);
					// 通知地图组件更新点位坐标
					if (this.$refs.olmap && this.$refs.olmap.pointPositionUpdate && elementData.id) {
						this.$refs.olmap.pointPositionUpdate(elementData.id, elementData.position);
					}
				}
				
				// 特殊处理：如果是多边形，需要更新颜色
				if (elementData.id && elementData.id.startsWith('s')) {
					if (this.$refs.olmap && this.$refs.olmap.editSnapeColor) {
						this.$refs.olmap.editSnapeColor(elementData.id);
					}
				}
				
				// 更新当前特征数据
				this.currentFeature = { ...elementData };
				this.haveDraw = true;
				
				// 刷新右侧列表中的元素信息
				this.updateElementInList(elementData);
				
				console.log('保存前验证元素数量:', this.resourcesFeature.length);
				
				// 自动保存到后端
				await this.saveRoute();
				
				console.log('保存后验证元素数量:', this.resourcesFeature.length);
				
				// 关闭Inspector
				this.inspector.visible = false;
				
				// 在地图上保持选中状态
				setTimeout(() => {
					if (this.$refs.olmap && this.$refs.olmap.selectShowEle && elementData.id) {
						this.$refs.olmap.selectShowEle(elementData.id);
					}
				}, 100);
				
				this.$message.success(`元素 ${elementData.id} 保存成功`);
			} catch (error) {
				console.error('保存元素失败:', error);
				this.$message.error('保存元素失败: ' + (error.message || '未知错误'));
			} finally {
				loading.close();
			}
		},
		
		// Inspector取消
		handleInspectorCancel() {
			this.inspector.visible = false;
			this.inspector.mode = 'view';
		},
		
		// Inspector关闭
		handleInspectorClose() {
			this.inspector.visible = false;
			this.inspector.mode = 'view';
			this.inspector.data = null;
		},
		
		// Inspector定位
		handleInspectorLocate(element) {
			if (this.$refs.olmap && this.$refs.olmap.selectShowEle && element && element.id) {
				this.$refs.olmap.selectShowEle(element.id);
				// 可以添加地图缩放和居中逻辑
			} else {
				console.warn('无法定位元素:', element);
			}
		},
		
		
		// Inspector高度变化
		handleInspectorHeightChange(height) {
			// 可以在这里处理高度变化后的布局调整
			console.log('Inspector高度变化为:', height);
		},
		
		// 更新元素列表中的元素信息
		updateElementInList(elementData) {
			const updateElementInArray = (array) => {
				const index = array.findIndex(item => item.id === elementData.id);
				if (index !== -1) {
					array[index] = { ...array[index], ...elementData };
				}
			};
			
			// 根据ID前缀更新对应数组
			if (elementData.id.startsWith('p')) {
				updateElementInArray(this.pointData);
			} else if (elementData.id.startsWith('l')) {
				updateElementInArray(this.lineData);
			} else if (elementData.id.startsWith('b')) {
				updateElementInArray(this.bowData);
			} else if (elementData.id.startsWith('s')) {
				updateElementInArray(this.shapeData);
			}
		},
		
		// === 地图事件处理（保留原有逻辑）===
		
		// 地图元素加载完毕的回执
		elementRoadInitEnd(features) {
			features.forEach(item => {
				// 检查 item.values_ 和 item.values_.id 是否存在
				if (item.values_ && item.values_.id) {
					const id = item.values_.id;
					const data = {
						id: id,
						name: item.values_.name,
						type: item.getGeometry().getType()
					};
					// 根据 id 前缀分类存入对应数组
					if (id.startsWith('p')) {
						this.pointData.push(data);
					} else if (id.startsWith('l')) {
						this.lineData.push(data);
					} else if (id.startsWith('b')) {
						this.bowData.push(data);
					} else if (id.startsWith('s')) {
						this.shapeData.push(data);
					}
				}
			});
			// 对分类后的数组按数字部分排序
		this.pointData.sort((a, b) => parseInt(a.id.split('_')[1]) - parseInt(b.id.split('_')[1]));
		this.lineData.sort((a, b) => parseInt(a.id.split('_')[1]) - parseInt(b.id.split('_')[1]));
		this.bowData.sort((a, b) => parseInt(a.id.split('_')[1]) - parseInt(b.id.split('_')[1]));
		this.shapeData.sort((a, b) => parseInt(a.id.split('_')[1]) - parseInt(b.id.split('_')[1]));
		// 过滤掉null值，确保resourcesFeature数组中只包含有效的feature对象
		this.resourcesFeature = features.filter(feature => feature !== null && feature !== undefined && typeof feature.getGeometry === 'function');
		console.log(`elementRoadInitEnd: 原始feature数量=${features.length}, 有效feature数量=${this.resourcesFeature.length}`);
		},
		// 某个元素绘制完成的回调
		elementRoadDrawEnd(feature) {
			const id = feature.values_.id || feature.getId();
			const data = {
				id: id,
				name: feature.values_.name,
				type: feature.getGeometry().getType()
			};
			if (id.startsWith('p')) {
				this.pointData.push(data);
				// 按照类型为feature初始化基础参数和高级参数(点)
				this.initElelmentParamsPonint(feature);
			} else if (id.startsWith('l')) {
				this.lineData.push(data);
				// 按照类型为feature初始化基础参数和高级参数(线)
				this.initElelmentParamsBowOrLine(feature);
			} else if (id.startsWith('b')) {
				this.bowData.push(data);
				// 按照类型为feature初始化基础参数和高级参数(曲线)
				this.initElelmentParamsBowOrLine(feature);
			} else if (id.startsWith('s')) {
				this.shapeData.push(data);
				// 按照类型为feature初始化基础参数和高级参数(面)
				this.initElelmentParamsSnape(feature);
			}
			// 标记当前存在绘制的操作,拦截使用
			this.haveDraw = true; // 是否操作过页面元素(新增修改或者删除元素) (在切换页面或者刷新时进行拦截,避免误操作退出页面)
		},
		// 查看某个元素
		watchEle(id) {
			// 调用地图组件显示元素
			if (this.$refs.olmap && this.$refs.olmap.selectShowEle && id) {
				this.$refs.olmap.selectShowEle(id);
			} else {
				console.warn('无法查看元素:', id);
			}
		},
		// 查看某个元素的子组件回调
		selectShowEleResult(feature) {
			const geometry = feature.getGeometry();
			console.log(geometry.getCoordinates());
			
			if (geometry.getType() == 'Point') {
				// 如果是点位则临时保存xyz和类型到参数用于渲染(保存时会移除)  注:保存元素坐标为参数用于对应表单数据,否则需要用方法获取,无法双向绑定
				feature.set('position', geometry.getCoordinates())
			} else if (geometry.getType() == "LineString") {
				// 解析线段类型的direct参数用于渲染和修改(保存时需要渲染回原始数据模式,切记)
				const value = feature.values_.direct - 100 || 0;
				const binary = value.toString(2).padStart(4, '0');
				const result = [
					binary[0] === '1',  // bit3
					binary[1] === '1',  // bit2
					binary[2] === '1',  // bit1
					binary[3] === '1'   // bit0
				];
				// 临时参数渲染使用, 保存时会删除
				feature.set('directList', result);
			}
			// 临时保存类型到参数用于渲染(保存时回移除)
			feature.set('typeEle', geometry.getType())
			
			// 准备元素数据并显示Inspector
			const elementData = {
				id: feature.getId(),
				name: feature.get('name') || '',
				type: geometry.getType(),
				...feature.getProperties()
			};
			
			this.showInspector(elementData, 'edit');
		},
		// 移除某个元素
		removeElement(id) {
			// 调用地图组件移除元素
			this.$refs.olmap.removeElement(id);
		},
		// 移除元素操作的回调
	removeElementResult(id) {
		if (!id) {
			this.$message.error('移除元素失败!');
			return;
		}
		
		console.log('删除元素前数量:', this.resourcesFeature.length);
		console.log('要删除的元素ID:', id);
		
		// 删除当前数据table中这个元素
		if (id.startsWith('p')) {
			const index = this.pointData.findIndex(item => item.id === id);
			if (index !== -1) {
				this.pointData.splice(index, 1);
			}
		}
		if (id.startsWith('l')) {
			const index = this.lineData.findIndex(item => item.id === id);
			if (index !== -1) {
				this.lineData.splice(index, 1);
			}
		}
		if (id.startsWith('b')) {
			const index = this.bowData.findIndex(item => item.id === id);
			if (index !== -1) {
				this.bowData.splice(index, 1);
			}
		}
		if (id.startsWith('s')) {
			const index = this.shapeData.findIndex(item => item.id === id);
			if (index !== -1) {
				this.shapeData.splice(index, 1);
			}
		}
		
		// 判断当前选择元素是否被删除,如果是则删除
		if (this.currentFeature && this.currentFeature.id == id) {
			this.currentFeature = {};
		}
		
		// 删除源features中的此元素
		const index = this.resourcesFeature.findIndex(feature => feature && feature.getId && feature.getId() == id);
		if (index !== -1) {
			console.log('从resourcesFeature中删除元素:', id);
			this.resourcesFeature.splice(index, 1);
			console.log('删除后数量:', this.resourcesFeature.length);
		} else {
			console.warn('在resourcesFeature中找不到要删除的元素:', id);
		}
		
		// 清理可能存在的null值
		this.resourcesFeature = this.resourcesFeature.filter(feature => feature !== null && feature !== undefined && typeof feature.getGeometry === 'function');
		
		this.haveDraw = true;
	},
		// 初始化点位元素基础和高级参数
		initElelmentParamsPonint(feature) {
			feature.set('name', '');
			feature.set('yaw', 0);	// 弧度
			// 如果是通过实时位姿则需要判断是否有值,有则设置
			feature.set('isyawfix', feature.get('isyawfix') ? true : false); // 偏航使能
			feature.set('taskid', 0);
			feature.set('offset', 0);
		feature.set('pitch', 0)
		feature.set('roll', 0)
		// 验证feature有效性后再添加
		if (feature && typeof feature.getGeometry === 'function') {
			this.resourcesFeature.push(feature);
		} else {
			console.warn('尝试添加无效的point feature:', feature);
		}
		},
	// 初始化执行元素基础和高级参数
	initElelmentParamsBowOrLine(feature) {
		feature.set('name', '');
		// direct中的值首先需要减去100，结果的后4位bit位分别代表如下含义：
		// bit3：为1时，表示允许车辆从起点行驶到终点，且机器人以正常前行的方式行驶；
		// bit2：为1时，表示允许车辆从起点行驶到终点，且机器人以倒车的方式行驶；
		// bit1：为1时，表示允许车辆从终点行驶到起点，且机器人以正常前行的方式行驶；
		// bit0：为1时，表示允许车辆从终点行驶到起点，且机器人以倒车的方式行驶。
		// 举例: direct=105(bit2和bit0为1)，表示为双向车道，但是不论机器人从起点前往终点，还是从终点前往起点，都会以倒车的方式行驶。
		feature.set('direct', 110); // 常用 110:起点至终点 + 终点至起点(双方向) 正向行驶    108:起点至终点 正向行驶
		// 🔧 补充robot_map_editor中的标准属性字段
		feature.set('chassistype', 10); // 底盘类型
		feature.set('plantype', 0); // 规划类型
		feature.set('controltype', 0); // 控制类型
		feature.set('obstype', 0); // 避障方式，0：停车等待，1：车道绕障，2：路网绕障，默认为0
		feature.set('runtype', 0); // 运行类型
		feature.set('roadwidth', 0); // 道路宽度
		feature.set('lanewidth', 1.0); // 车道宽度
		feature.set('leftlanenum', 0); //前进方向左侧车道数
		feature.set('rightlanenum', 0); //前进方向右侧车道数
		feature.set('maxspeed', 0.5); // 最大限速  m/s
		feature.set('minspeed', 0.0); // 最小限速  m/s
		feature.set('maxtheta', 1.0); // 最大转向角
		feature.set('mintheta', -1.0); // 最小转向角（修正为-1.0）
		feature.set('selftheta', 0.5); // 自身角度
		feature.set('xytolerance', 0.2); // 平面坐标容差
		feature.set('thtolerance', 0.2); // 角度容差（修正为0.2）
		feature.set('slowdis', 2.0); // 减速距离
		feature.set('followdis', 0.4); // 跟随距离
		feature.set('obsvalue', 200); // 障碍物参数（例如：权重值或影响范围）
		feature.set('s2eforward', 0.0); // 机器人沿当前线段从起点到达终点时多行驶(负数则为少行驶)的距离，单位为米，默认为0
		feature.set('e2sforward', 0.0); // 机器人沿当前线段从终点到达起点时多行驶的距离，单位为米，默认为0

		// 验证feature有效性后再添加
		if (feature && typeof feature.getGeometry === 'function') {
			this.resourcesFeature.push(feature);
		} else {
			console.warn('尝试添加无效的line/bow feature:', feature);
		}
		},
		// 初始化面元素基础和高级参数
		initElelmentParamsSnape(feature) {
			feature.set('name', '');
			feature.set('typeEle', feature.getGeometry().getType()); // 保存元素类型为参数用于动态绑定对应的元素修改表单,否则需要用方法获取
			feature.set('color', "#7EFFFA");
			//区域类型,说明: 0：隔离区域，限定机器人只能在该区域活动；1：装饰区域，仅人机交互用，不影响导航；
			// 2：禁行区域，不允许机器人进入该区域；3：会车管制区，特定场景使用；
			// 4：道闸管控区，特定场景使用；11：GPS定位区，进入该区域后，从激光定位切换到GPS定位；
			// 22：动态禁行区，特定场景使用。
		feature.set('type', 1);
		feature.set('transparent', 200);
		// 验证feature有效性后再添加
		if (feature && typeof feature.getGeometry === 'function') {
			this.resourcesFeature.push(feature);
		} else {
			console.warn('尝试添加无效的shape feature:', feature);
		}
		},
		/**
		 * 点位坐标修改
		 */
		positionEdit() {
			this.haveDraw = true;
			this.$refs.olmap.pointPositionUpdate(this.currentFeature.id, this.currentFeature.position);
		},
		// 自定义参数修改提交
		setProperties() {
			if (!this.currentFeature) return;
			this.resourcesFeature.forEach(item => {
				if (item.getId() == this.currentFeature.id) {
					// 额外参数处理 线
					if (this.currentFeature.id.startsWith('l') || this.currentFeature.id.startsWith('b')) {
						// direct还原
						let directList = this.currentFeature.directList;
						// 将布尔集合转成4位bit集合, 再转成10进制, 加100还原成原始报文
						const binaryString = directList.map(bit => (bit ? '1' : '0')).join('');
						const value = parseInt(binaryString, 2);
						const direct = value + 100;
						this.currentFeature.direct = direct;
					}
					// 处理完毕后先刷新对象到画布
					item.setProperties(this.currentFeature)
					// 刷新完毕后用自定义参数处理其他需要修改完毕能看到的元素效果(例如修改name或者图形颜色等)
					if (this.currentFeature.id.startsWith('s')) {
						// 额外处理多边形的效果
						// 1. 修改图形的颜色,文本
						this.$refs.olmap.editSnapeColor(this.currentFeature.id);
					}
				}
			})
			this.haveDraw = true; // 是否操作过页面元素(新增修改或者删除元素) (在切换页面或者刷新时进行拦截,避免误操作退出页面)
		},
		// 保存路网
	async saveRoute(validateAfterSave = false) {
		try {
			console.log('保存前元素数量:', this.resourcesFeature.length);
			console.log('保存前元素列表:', this.resourcesFeature.map(f => f.getId()));
			
			// 构建GeoJSON数据（不修改原始数据）
			const geoJsonData = this.buildGeoJsonData();
			console.log('构建的GeoJSON数据:', geoJsonData);
			
		// 允许保存空的路网数据（即删除所有元素的情况）
		// 如果是空路网，给用户友好提示
		if (!geoJsonData.features || geoJsonData.features.length === 0) {
			console.log('检测到空路网，将保存空数据');
		}
		
		// 调用API保存路网数据
		try {
			await this.saveRoadMapToServer(geoJsonData);
		} catch (error) {
			// 如果后端不支持空路网保存，捕获错误并给出更友好的提示
			if (error.message && error.message.includes('原有序列')) {
				// 如果是空路网且后端返回"原有序列"相关错误，说明后端不支持空数据
				// 这种情况下我们认为删除成功（因为确实已经删除了）
				if (geoJsonData.features.length === 0) {
					console.warn('后端不支持保存空路网，但本地已清空所有元素');
					this.haveDraw = false;
					this.$message.success('已删除所有元素（路网已清空）');
					return; // 提前返回，不再抛出错误
				}
			}
			// 其他错误继续抛出
			throw error;
		}
				
				console.log('保存后元素数量:', this.resourcesFeature.length);
				console.log('保存后元素列表:', this.resourcesFeature.map(f => f.getId()));
				
				// 可选的保存后验证（主要用于调试）
				if (validateAfterSave) {
					try {
						console.log('正在验证保存结果...');
						const savedData = await getRoadMapGeoJson(this.mapName);
						if (savedData && savedData.features) {
							console.log('服务器上的元素数量:', savedData.features.length);
							if (savedData.features.length !== geoJsonData.features.length) {
								console.warn('警告：保存的元素数量与本地数量不匹配', {
									local: geoJsonData.features.length,
									server: savedData.features.length
								});
							}
						}
					} catch (validateError) {
						console.warn('保存后验证失败:', validateError);
						// 验证失败不影响主流程
			}
		}
		
		// 保存成功
		this.haveDraw = false;
		
		// 根据元素数量显示不同的消息
		if (geoJsonData.features.length === 0) {
			this.$message.success('路网已清空并保存');
		} else {
			this.$message.success(`路网数据保存成功，共${geoJsonData.features.length}个元素`);
		}
	} catch (error) {
		console.error('保存路网数据失败:', error);
		this.$message.error('保存路网数据失败: ' + (error.message || '未知错误'));
		throw error; // 重新抛出错误，让调用者知道保存失败
	}
},

		// 清理坐标数据，将null值替换为0
		cleanCoordinates(coordinates) {
			if (!coordinates) return coordinates;
			
			// 递归处理多维数组
			if (Array.isArray(coordinates)) {
				return coordinates.map(coord => {
					if (Array.isArray(coord)) {
						// 如果是嵌套数组，递归处理
						return this.cleanCoordinates(coord);
					} else {
						// 如果是数值，将null或undefined替换为0
						return (coord === null || coord === undefined) ? 0 : coord;
					}
				});
			}
			
			return coordinates;
		},

		// 构建GeoJSON数据
		buildGeoJsonData() {
			// 验证resourcesFeature数组
			if (!this.resourcesFeature || this.resourcesFeature.length === 0) {
				console.warn('buildGeoJsonData: resourcesFeature数组为空');
				return {
					type: "FeatureCollection",
					features: [],
					map: this.mapName
				};
			}
			
		console.log('构建GeoJSON数据，元素数量:', this.resourcesFeature.length);
		
		// 首先过滤掉null或undefined的feature对象
		const validFeatures = this.resourcesFeature.filter(feature => feature !== null && feature !== undefined);
		console.log('有效元素数量:', validFeatures.length);
		
		const features = validFeatures.map(feature => {
			try {
				// 再次确认feature是有效的
				if (!feature || typeof feature.getProperties !== 'function') {
					console.warn('发现无效的feature对象:', feature);
					return null;
				}
				
				const properties = { ...feature.getProperties() };
				const geometry = feature.getGeometry();
					
					// 验证几何对象
					if (!geometry) {
						console.warn('发现无效的几何对象，跳过元素:', feature.getId());
						return null;
					}
					
					// 确保包含ID
					if (!properties.id) {
						properties.id = feature.getId();
					}
					
			// 清理临时渲染属性（不修改原始数据，只在保存时清理）
			const cleanProperties = { ...properties };
			delete cleanProperties.typeEle;      // 删除临时类型属性
			delete cleanProperties.position;     // 删除临时位置属性  
			delete cleanProperties.directList;   // 删除临时方向列表属性
			delete cleanProperties.geometry;     // 删除OpenLayers几何对象，避免嵌套
			delete cleanProperties.bezierControlPoints; // 删除贝塞尔控制点（已用于导出坐标）
			
			// 🔧 删除可能存在的错误type字段（LineString/Point等）
			// 这个字段可能来自历史数据，会干扰导航算法
			// 注意：Polygon的type字段是合法的区域类型（0-22），不应删除
			if (geometry.getType() !== 'Polygon' && cleanProperties.type !== undefined) {
				console.warn(`删除元素 ${properties.id} 中的错误type字段:`, cleanProperties.type);
				delete cleanProperties.type;
			}
					
			// 获取原始坐标并清理null值
			const originalCoordinates = geometry.getCoordinates();
			const cleanedCoordinates = this.cleanCoordinates(originalCoordinates);
			
			// 🔧 根据robot_map_editor的正确逻辑处理线段导出
			let exportGeometryType = geometry.getType();
			let exportCoordinates = cleanedCoordinates;
			
		// 处理LineString类型的元素
		if (geometry.getType() === 'LineString') {
			const featureId = properties.id;
			
			if (featureId && featureId.startsWith('b_')) {
				// 贝塞尔曲线：导出为MultiPoint，使用保存的完整控制点
				exportGeometryType = 'MultiPoint';
				
				// 🔧 优先使用保存的原始控制点（bezierControlPoints属性）
				if (properties.bezierControlPoints && Array.isArray(properties.bezierControlPoints)) {
					exportCoordinates = this.cleanCoordinates(properties.bezierControlPoints);
					console.log(`🔄 贝塞尔曲线 ${featureId} 转换: LineString(${cleanedCoordinates.length}点) → MultiPoint(${exportCoordinates.length}控制点)`);
				} else {
					// 兼容旧数据：如果没有保存控制点，只使用起点和终点
					exportCoordinates = [
						cleanedCoordinates[0],  // 起点
						cleanedCoordinates[cleanedCoordinates.length - 1]  // 终点
					];
					console.warn(`⚠️ 贝塞尔曲线 ${featureId} 缺少控制点数据，只保存起点和终点`);
				}
			} else {
				// 普通LineString：只保存起点和终点
				// 这是关键修复！避免中间可能被错误插入的顶点影响导航
				exportGeometryType = 'LineString';
				exportCoordinates = [
					cleanedCoordinates[0],  // 起点
					cleanedCoordinates[cleanedCoordinates.length - 1]  // 终点
				];
				console.log(`📏 普通线段 ${featureId} 优化: LineString(${cleanedCoordinates.length}点) → LineString(2点)`);
			}
		}
			
			// 🔧 修复Point坐标：确保Point类型有3个坐标值（x, y, z）
			if (exportGeometryType === 'Point' && exportCoordinates.length === 2) {
				exportCoordinates.push(0.0); // 添加z坐标
			}
				
				return {
					type: "Feature",
					properties: cleanProperties,
					geometry: {
						type: exportGeometryType,
						coordinates: exportCoordinates
					}
				};
				} catch (error) {
					console.error('处理元素时出错:', feature.getId(), error);
					return null;
				}
			}).filter(feature => feature !== null); // 过滤掉无效的元素

			const result = {
				type: "FeatureCollection",
				features: features,
				map: this.mapName // 添加地图名称
			};
			
			console.log('构建完成，有效元素数量:', features.length);
			return result;
		},

		// 保存路网数据到服务器
		async saveRoadMapToServer(geoJsonData) {
			try {
				console.log('正在发送路网数据到服务器:', { data: geoJsonData });
				
				// 使用封装好的API函数
				const response = await saveRoadMapGeoJson(geoJsonData);
				
				console.log('服务器响应:', response);
				
				// 检查响应数据中的status字段
				if (response && response.status === true) {
					return response;
				} else {
					throw new Error('保存失败：服务器返回状态为false');
				}
		} catch (error) {
			console.error('保存路网数据失败:', error);
			if (error.response) {
				// 服务器响应了错误状态码
				// 尝试从响应数据中提取详细错误信息
				let errorMsg = '服务器错误';
				if (error.response.data) {
					if (typeof error.response.data === 'string') {
						errorMsg = error.response.data;
					} else if (error.response.data.message) {
						errorMsg = error.response.data.message;
					} else if (error.response.data.msg) {
						errorMsg = error.response.data.msg;
					} else {
						errorMsg = JSON.stringify(error.response.data);
					}
				}
				throw new Error(`${errorMsg}`);
			} else if (error.request) {
				// 请求发送了但没有收到响应
				throw new Error('网络错误: 无法连接到服务器');
			} else {
				// 其他错误
				throw new Error(`请求配置错误: ${error.message}`);
			}
		}
	},
		// === 添加当前点对话框处理 ===
		
		// 打开添加当前点对话框
		openCurrentToMapDialog() {
			this.currentRobotRecord = {
				x: this.robotPoseData.x || 0,
				y: this.robotPoseData.y || 0,
				z: 0,
				angle: this.robotPoseData.angle || 0,
				angleEnable: false
			};
		},
		
		// 添加当前点到地图
		addCurrentToMap() {
			this.$refs.currentPointForm.validate((valid) => {
				if (valid) {
			this.addCurrentMapShow = false;
			// 使用组件的根据坐标绘制点方法
					const data = [
						{ yaw: this.currentRobotRecord.angle }, 
						{ isyawfix: this.currentRobotRecord.angleEnable }
					];
					this.$refs.olmap && this.$refs.olmap.createPointAtCoordinateForImport && 
					this.$refs.olmap.createPointAtCoordinateForImport(
						[this.currentRobotRecord.x, this.currentRobotRecord.y, this.currentRobotRecord.z || 0], 
						'', 
						data
					);
					this.$message.success('已添加当前位姿点到地图');
				}
			});
		}
	}
};
</script>

<style lang="scss" scoped>
@import './components/shared/_map-shared.scss';

.edit-page {
  height: calc(100vh - 84px);
  display: flex;
  flex-direction: column;
  background: #f5f7fa;
	position: relative;
  overflow: hidden;
  
  /* CSS变量：定义安全区域 */
  --left-safe: 88px;                    /* 左边工具栏+内边距的安全距离 */
  --right-panel-width: 380px;           /* 右侧面板宽度，由JS动态更新 */
  --right-gutter: 32px;                 /* 右侧间隙 */
  --right-safe: calc(var(--right-panel-width) + var(--right-gutter));
}

.map-container {
  flex: 1;
  display: flex;
  position: relative;
  min-height: 0;
}

.toolbar-container {
  position: absolute;
  top: 16px;
  left: 16px;
  z-index: $map-z-index-toolbar;
  pointer-events: none;
  
  > * {
    pointer-events: auto;
  }
}

#map-stage {
  flex: 1;
  position: relative;  /* 让子元素 absolute 以此为参照 */
  background: #f5f5f5;
  overflow: hidden;    /* 防止子元素视觉溢出 */
}

.panel-container {
  // 编辑页面板现在使用 fixed 定位，容器不需要特殊样式
  pointer-events: none;
  
  > * {
    pointer-events: auto;
  }
}

// 对话框样式优化
:deep(.el-dialog) {
  border-radius: 12px;
  box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1);
  
  .el-dialog__header {
    padding: 20px 24px 10px;
    border-bottom: 1px solid #e4e7ed;
    
    .el-dialog__title {
      font-size: 18px;
      font-weight: 600;
      color: #303133;
    }
  }
  
  .el-dialog__body {
    padding: 20px 24px;
  }
  
  .el-dialog__footer {
    padding: 10px 24px 20px;
    text-align: right;
    
    .el-button {
      margin-left: 12px;
      
      &:first-child {
        margin-left: 0;
      }
    }
  }
}

// 表单样式优化
:deep(.el-form) {
  .el-form-item {
    margin-bottom: 18px;
    
    .el-form-item__label {
      font-weight: 500;
      color: #374151;
      line-height: 1.6;
    }
    
    .el-form-item__content {
      line-height: 1.6;
    }
  }
  
  .el-input {
    .el-input__inner {
      border-radius: 8px;
      border: 1px solid #d1d5db;
      transition: all 0.2s ease;
      
      &:focus {
        border-color: #3b82f6;
        box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
      }
    }
  }
  
  .el-input-number {
	width: 100%;
    
    .el-input__inner {
      border-radius: 8px;
      border: 1px solid #d1d5db;
      text-align: left;
      
      &:focus {
        border-color: #3b82f6;
        box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
      }
    }
  }
  
  .el-switch {
    .el-switch__core {
      border-radius: 12px;
    }
  }
}

// 响应式适配
@media (max-width: 1200px) {
  .panel-container {
    right: 8px;
    top: 8px;
  }
  
  .toolbar-container {
    left: 8px;
    top: 8px;
  }
}

@media (max-width: 768px) {
  .edit-page {
    .map-container {
	flex-direction: column;
    }
    
    .panel-container {
      position: relative;
      top: auto;
      right: auto;
	width: 100%;
      z-index: auto;
    }
    
    .toolbar-container {
	position: relative;
      top: auto;
      left: auto;
      z-index: auto;
	margin-bottom: 8px;
    }
  }
}

// 暗色主题适配
html.dark {
  .edit-page {
    background: #1f2937;
    
    .map-content {
      background: #374151;
    }
  }
}

// 动画效果
@keyframes fadeInUp {
  from {
    opacity: 0;
    transform: translateY(20px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.edit-page {
  animation: fadeInUp 0.3s ease-out;
}

/* === 添加当前点弹框样式（参考导航页目标点编辑弹框） === */
/* 全局弹框居中样式 */
.centered-dialog {
  display: flex !important;
  align-items: center !important;
  justify-content: center !important;
}

.add-pose-dialog {
  ::v-deep .el-dialog {
    border-radius: 12px;
    overflow: hidden;
    box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
    margin: 0 auto;
    position: relative;
    top: 50%;
    transform: translateY(-50%);
    max-height: 90vh;
    overflow-y: auto;
  }

  /* 确保弹框在页面中居中 */
  ::v-deep .el-dialog__wrapper {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 100vh;
  }
  
  /* 移除默认的margin-top */
  ::v-deep .el-dialog {
    margin-top: 0 !important;
    margin-bottom: 0 !important;
  }

  ::v-deep .el-dialog__header {
    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
    padding: 20px 24px;
    margin: 0;
    border-radius: 12px 12px 0 0;

    .el-dialog__title {
      color: white;
      font-size: 18px;
      font-weight: 600;
    }
    
    .el-dialog__close {
      color: white;
      font-size: 18px;
      
      &:hover {
        color: #f0f0f0;
      }
    }
  }
  
  ::v-deep .el-dialog__body {
    padding: 24px;
    background: #f8fafc;
    margin: 0;
    max-height: calc(90vh - 120px);
    overflow-y: auto;
  }
  
  ::v-deep .el-dialog__footer {
    padding: 16px 24px 24px;
    background: #f8fafc;
    border-top: 1px solid #e2e8f0;
    border-radius: 0 0 12px 12px;
    margin: 0;
  }
}

.pose-form {
  .el-form-item {
    margin-bottom: 14px;
	display: flex;
	align-items: center;
    
    &:last-child {
      margin-bottom: 0;
    }
    
    .el-form-item__content {
      flex: 1;
      margin-left: 0;
    }
  }
  
  .coordinate-input {
    margin-bottom: 4px;
  }
  
  .el-form-item__label {
    font-weight: 600;
    color: #2d3748;
    padding-right: 12px;
    min-width: 100px;
    font-size: 14px;
    line-height: 44px;
    height: 44px;
	display: flex;
	align-items: center;
    margin-bottom: 0;
  }
  
  .coordinate-input {
    ::v-deep .el-input__inner {
      border-radius: 8px;
      border: 1px solid #e2e8f0;
      height: 44px;
      font-size: 15px;
      padding: 0 16px;
      background: #ffffff;
      transition: all 0.2s ease;
      
      &:focus {
        border-color: #667eea;
        box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1);
        background: #fafbff;
      }
      
      &:hover {
        border-color: #cbd5e0;
      }
    }
  }
  
  ::v-deep .el-input-number {
    width: 100%;
    
    .el-input__inner {
      border-radius: 6px;
      border: 1px solid #e2e8f0;
      height: 40px;
      font-size: 14px;
      padding: 0 12px;
      
      &:focus {
        border-color: #667eea;
        box-shadow: 0 0 0 2px rgba(102, 126, 234, 0.1);
      }
    }
  }
}

.dialog-content {
  .form-section {
    background: white;
    border-radius: 10px;
    padding: 20px;
    margin-bottom: 16px;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
    border: 1px solid #f1f5f9;
    
    &:last-child {
      margin-bottom: 0;
    }
    
    .section-title {
      display: flex;
      align-items: center;
      margin: 0 0 16px 0;
      font-size: 15px;
      font-weight: 600;
      color: #2d3748;
      border-bottom: 2px solid #e2e8f0;
      padding-bottom: 8px;
      
      i {
        margin-right: 10px;
        color: #667eea;
        font-size: 18px;
      }
    }
  }
}
</style>