<template>
  <div class="flex-1 h-full w-full bg-base-200 relative overflow-hidden diagram-container" ref="canvasContainer"
      @mousedown="handleCanvasMouseDown"
      @mousedown.middle.prevent="startMiddleDrag"
      @wheel.prevent="onZoom"
      @contextmenu.prevent="handleContextMenu">
    <!-- 工具栏 -->
    <div class="absolute top-2 right-2 flex gap-2 z-30">
      <button class="btn btn-sm btn-primary" @click="openDiagramFileSelector">
        <svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4 mr-1" fill="none" viewBox="0 0 24 24" stroke="currentColor">
          <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 19a2 2 0 01-2-2V7a2 2 0 012-2h4l2 2h4a2 2 0 012 2v1M5 19h14a2 2 0 002-2v-5a2 2 0 00-2-2H9a2 2 0 00-2 2v5a2 2 0 01-2 2z" />
        </svg>
        导入
      </button>
      <button class="btn btn-sm btn-primary" @click="exportDiagram">
        <svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4 mr-1" fill="none" viewBox="0 0 24 24" stroke="currentColor">
          <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4" />
        </svg>
        导出
      </button>
      <button class="btn btn-sm btn-primary" @click="emit('open-components')">
        <svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4 mr-1" fill="none" viewBox="0 0 24 24" stroke="currentColor">
          <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4v16m8-8H4" />
        </svg>
        添加组件
      </button>
    </div>
    
    <!-- 隐藏的文件输入 -->
    <input 
      type="file" 
      ref="fileInput" 
      class="hidden" 
      accept=".json" 
      @change="handleFileSelected"
    />
    
    <div
      ref="canvas"
      class="diagram-canvas"
      :style="{ transform: `translate(${position.x}px, ${position.y}px) scale(${scale})` }">        <!-- 渲染连线 -->
      <svg class="wires-layer" width="10000" height="10000">
        <!-- 已完成的连线 -->
        <WireComponent
          v-for="(wire, index) in wireItems"
          :key="wire.id"
          :id="wire.id"
          :start-x="wire.startX"
          :start-y="wire.startY"
          :end-x="wire.endX"
          :end-y="wire.endY"
          :stroke-color="wire.color || '#4a5568'"
          :stroke-width="wire.strokeWidth"
          :is-active="false"
          :start-component-id="wire.startComponentId"
          :start-pin-id="wire.startPinId"
          :end-component-id="wire.endComponentId"
          :end-pin-id="wire.endPinId"
          :routing-mode="wire.routingMode"
          :path-commands="wire.pathCommands"
        />
        
        <!-- 正在创建的连线 -->
        <WireComponent
          v-if="isCreatingWire"
          id="temp-wire"
          :start-x="creatingWireStart.x"
          :start-y="creatingWireStart.y"
          :end-x="mousePosition.x"
          :end-y="mousePosition.y"
          stroke-color="#3182ce"
          :stroke-width="2"
          :is-active="true"
        />
      </svg>
      
      <!-- 渲染画布上的组件 -->
      <div v-for="component in diagramParts" :key="component.id"
          class="component-wrapper"          :class="{
            'component-hover': hoveredComponent === component.id,
            'component-selected': selectedComponentId === component.id,
            'component-disabled': !component.isOn,
            'component-hidepins': component.hidepins
          }"          :style="{ 
            top: component.y + 'px', 
            left: component.x + 'px',
            zIndex: component.index ?? 0,
            transform: component.rotate ? `rotate(${component.rotate}deg)` : 'none',
            opacity: component.isOn ? 1 : 0.6,
            display: 'block'
          }"
          @mousedown.left.stop="startComponentDrag($event, component)"
          @mouseover="hoveredComponent = component.id"
          @mouseleave="hoveredComponent = null">        <!-- 动态渲染组件 -->
        <component          :is="getComponentDefinition(component.type)"
          v-if="props.componentModules[component.type]"
          v-bind="prepareComponentProps(component.attrs || {}, component.id)"          @update:bindKey="(value: string) => updateComponentProp(component.id, 'bindKey', value)"          @pin-click="(pinInfo: any) => handlePinClick(component.id, pinInfo, pinInfo.originalEvent)"          :ref="(el: any) => setComponentRef(component.id, el)"
        />
         
        <!-- Fallback if component module not loaded yet -->
        <div v-else class="p-2 text-xs text-gray-400 border border-dashed border-gray-400 flex items-center justify-center">
          <div class="flex flex-col items-center">
            <div class="loading loading-spinner loading-xs mb-1"></div>
            <span>Loading {{ component.type }}...</span>
          </div>
        </div>
      </div>
    </div>

    <!-- 通知组件 -->
    <div v-if="showNotification" class="toast toast-top toast-center z-50 w-fit-content">
      <div :class="`alert ${notificationType === 'success' ? 'alert-success' : 
                            notificationType === 'error' ? 'alert-error' : 
                            'alert-info'}`">
        <span>{{ notificationMessage }}</span>
      </div>
    </div>

    <!-- 加载指示器 -->
    <div v-if="isLoading" class="absolute inset-0 bg-black bg-opacity-30 flex items-center justify-center z-50">
      <div class="loading loading-spinner loading-lg text-primary"></div>
    </div>

    <!-- 缩放指示器 -->
    <div class="absolute bottom-4 right-4 bg-base-100 px-3 py-1.5 rounded-md shadow-md z-20" style="opacity: 0.9;">
      <span class="text-sm font-medium">{{ Math.round(scale * 100) }}%</span>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, onMounted, onUnmounted, computed, watch } from 'vue';
import WireComponent from './equipments/Wire.vue';

// 导入 diagram 管理器
import { 
  loadDiagramData, saveDiagramData, 
  updatePartPosition, updatePartAttribute, 
  deletePart, addConnection, deleteConnection, 
  findConnectionsByPart, moveGroupComponents,
  parseConnectionPin, connectionArrayToWireItem,
  validateDiagramData
} from './diagramManager';

import type { DiagramData, DiagramPart, ConnectionArray, WireItem } from './diagramManager';

// 右键菜单处理函数
function handleContextMenu(e: MouseEvent) {
  e.preventDefault();
}

// 定义组件发出的事件
const emit = defineEmits(['diagram-updated', 'component-selected', 'component-moved', 'component-delete', 'wire-created', 'wire-deleted', 'load-component-module', 'open-components']);

// 定义组件接受的属性
const props = defineProps<{
  componentModules: Record<string, any>
}>();

// --- 画布状态 ---
const canvasContainer = ref<HTMLElement | null>(null);
const canvas = ref<HTMLElement | null>(null);
const position = reactive({ x: 0, y: 0 });
const scale = ref(1);
const isDragging = ref(false);
const isMiddleDragging = ref(false);
const dragStart = reactive({ x: 0, y: 0 });
const selectedComponentId = ref<string | null>(null);
const hoveredComponent = ref<string | null>(null);
const draggingComponentId = ref<string | null>(null);
const componentDragOffset = reactive({ x: 0, y: 0 });

// Diagram 数据
const diagramData = ref<DiagramData>({
  version: 1,
  author: 'admin',
  editor: 'me',
  parts: [],
  connections: []
});

// 组件引用跟踪
const componentRefs = ref<Record<string, any>>({});

// 计算属性：从 diagramData 中提取组件列表，并按index属性排序
const diagramParts = computed<DiagramPart[]>(() => {
  // 克隆原始数组以避免直接修改原始数据
  const parts = [...diagramData.value.parts];
  
  // 按照index属性进行排序，index值大的排在后面（显示在上层）
  // 如果没有定义index则默认为0
  return parts.sort((a, b) => {
    const indexA = a.index ?? 0;
    const indexB = b.index ?? 0;
    return indexA - indexB;
  });
});

// 计算属性：转换连接为 WireItem 列表以供渲染
const wireItems = computed<WireItem[]>(() => {
  // 检查组件是否仍然挂载
  if (!document.body.contains(canvasContainer.value)) {
    return []; // 如果组件已经卸载，返回空数组
  }
  
  return diagramData.value.connections.map((conn, index) => {
    const [startPin, endPin] = conn;
    const { componentId: startCompId, pinId: startPinId } = parseConnectionPin(startPin);
    const { componentId: endCompId, pinId: endPinId } = parseConnectionPin(endPin);
    
    // 查找对应的组件位置
    const startComp = diagramParts.value.find(p => p.id === startCompId);
    const endComp = diagramParts.value.find(p => p.id === endCompId);
    
    // 默认位置（如果找不到组件）
    const startPos = { x: 0, y: 0 };
    const endPos = { x: 0, y: 0 };
    
    // 如果找到组件，设置连线端点位置
    if (startComp) {
      startPos.x = startComp.x;
      startPos.y = startComp.y;
      
      // 尝试获取引脚精确位置（如果有实现）
      const startCompRef = componentRefs.value?.[startCompId];
      if (startCompRef && typeof startCompRef.getPinPosition === 'function') {
        try {
          const pinPos = startCompRef.getPinPosition(startPinId);
          console.log(`线路${index} - 起点引脚位置(来自${startCompId}):`, pinPos);
          
          if (pinPos) {
            // 正确合并组件位置与引脚相对位置
            startPos.x = startComp.x + pinPos.x;
            startPos.y = startComp.y + pinPos.y;
            console.log(`线路${index} - 计算后的起点位置:`, startPos);
          }
        } catch (error) {
          console.error(`获取引脚位置出错:`, error);
        }
      }
    }
    
    if (endComp) {
      endPos.x = endComp.x;
      endPos.y = endComp.y;
      
      // 尝试获取引脚精确位置
      const endCompRef = componentRefs.value?.[endCompId];
      if (endCompRef && typeof endCompRef.getPinPosition === 'function') {
        try {
          const pinPos = endCompRef.getPinPosition(endPinId);
          console.log(`线路${index} - 终点引脚位置(来自${endCompId}):`, pinPos);
          
          if (pinPos) {
            // 正确合并组件位置与引脚相对位置
            endPos.x = endComp.x + pinPos.x;
            endPos.y = endComp.y + pinPos.y;
            console.log(`线路${index} - 计算后的终点位置:`, endPos);
          }
        } catch (error) {
          console.error(`获取引脚位置出错:`, error);
        }
      }
    }
    
    return connectionArrayToWireItem(conn, index, startPos, endPos);
  });
});

// 连线创建状态
const isCreatingWire = ref(false);
const creatingWireStart = reactive({ x: 0, y: 0 });
const creatingWireStartInfo = reactive({
  componentId: '',
  pinId: '',
  constraint: ''
});
const mousePosition = reactive({ x: 0, y: 0 });

// 加载状态
const isLoading = ref(false);

// 通知状态
const showNotification = ref(false);
const notificationMessage = ref('');
const notificationType = ref<'success' | 'error' | 'info'>('info');
// 保存toast定时器ID
const toastTimers: number[] = [];

// 文件选择引用
const fileInput = ref<HTMLInputElement | null>(null);

// --- 缩放功能 ---
const MIN_SCALE = 0.2;
const MAX_SCALE = 10.0;

function onZoom(e: WheelEvent) {
  e.preventDefault();
  
  if (!canvasContainer.value) return;
  
  // 获取容器的位置
  const containerRect = canvasContainer.value.getBoundingClientRect();
  
  // 计算鼠标在容器内的相对位置
  const mouseX = e.clientX - containerRect.left;
  const mouseY = e.clientY - containerRect.top;
  
  // 计算鼠标在画布坐标系中的位置
  const mouseXCanvas = (mouseX - position.x) / scale.value;
  const mouseYCanvas = (mouseY - position.y) / scale.value;
  
  // 计算缩放值
  const zoomFactor = 1.1; // 每次放大/缩小10%
  const direction = e.deltaY > 0 ? -1 : 1;
  
  // 计算新的缩放值
  let newScale = direction > 0 ? scale.value * zoomFactor : scale.value / zoomFactor;
  newScale = Math.max(MIN_SCALE, Math.min(newScale, MAX_SCALE));
  
  // 计算新的位置，使鼠标指针位置在缩放前后保持不变
  position.x = mouseX - mouseXCanvas * newScale;
  position.y = mouseY - mouseYCanvas * newScale;
  
  // 更新缩放值
  scale.value = newScale;
}

// --- 动态组件渲染 ---
const getComponentDefinition = (type: string) => {
  const module = props.componentModules[type];
  if (!module) return null;
  
  // 确保我们返回一个有效的组件定义
  if (module.default) {
    return module.default;
  } else if (module.__esModule && module.default) {
    // 有时 Vue 的动态导入会将默认导出包装在 __esModule 属性下
    return module.default;
  } else {
    console.warn(`Module for ${type} found but default export is missing`, module);
    return null;
  }
};

function prepareComponentProps(attrs: Record<string, any>, componentId?: string): Record<string, any> {
  const result: Record<string, any> = { ...attrs };
  if (componentId) {
    result.componentId = componentId;
  }
  return result;
}

// 设置组件引用
function setComponentRef(componentId: string, el: any) {
  if (componentRefs.value) {
    if (el) {
      componentRefs.value[componentId] = el;
    } else {
      delete componentRefs.value[componentId];
    }
  }
}

// 重置组件引用缓存
function resetComponentRefs() {
  componentRefs.value = {};
}

// 加载组件模块
async function loadComponentModule(type: string) {
  if (!props.componentModules[type]) {
    try {
      // 通知父组件需要加载此类型的组件
      emit('load-component-module', type);
    } catch (error) {
      console.error(`Failed to request component module ${type}:`, error);
    }
  }
}

// --- 画布交互逻辑 ---
function handleCanvasMouseDown(e: MouseEvent) {
  // 如果是直接点击画布（而不是元器件），清除选中状态
  if (e.target === canvasContainer.value || e.target === canvas.value) {
    if (selectedComponentId.value !== null) {
      selectedComponentId.value = null;
      emit('component-selected', null);
    }
  }
  
  // 左键拖拽画布逻辑
  if (e.button === 0 && (e.target === canvasContainer.value || e.target === canvas.value)) {
    startDrag(e);
  }
}

// 左键拖拽画布
function startDrag(e: MouseEvent) {
  if (e.button !== 0 || draggingComponentId.value) return;

  isDragging.value = true;
  isMiddleDragging.value = false;
  dragStart.x = e.clientX - position.x;
  dragStart.y = e.clientY - position.y;
  
  document.addEventListener('mousemove', onDrag);
  document.addEventListener('mouseup', stopDrag);
  e.preventDefault();
}

// 中键拖拽画布
function startMiddleDrag(e: MouseEvent) {
  if (e.button !== 1) return;

  isMiddleDragging.value = true;
  isDragging.value = false;
  draggingComponentId.value = null;
  
  dragStart.x = e.clientX - position.x;
  dragStart.y = e.clientY - position.y;
  
  document.addEventListener('mousemove', onDrag);
  document.addEventListener('mouseup', stopDrag);
  e.preventDefault();
}

// 拖拽画布过程
function onDrag(e: MouseEvent) {
  if (!isDragging.value && !isMiddleDragging.value) return;

  position.x = e.clientX - dragStart.x;
  position.y = e.clientY - dragStart.y;
}

// 停止拖拽画布
function stopDrag() {
  isDragging.value = false;
  isMiddleDragging.value = false;
  
  document.removeEventListener('mousemove', onDrag);
  document.removeEventListener('mouseup', stopDrag);
}

// --- 组件拖拽交互 ---
function startComponentDrag(e: MouseEvent, component: DiagramPart) {
  const target = e.target as HTMLElement;
  
  // 检查点击的是否为交互元素 (如按钮、开关等)
  const isInteractiveElement = (
    target.tagName === 'rect' || 
    target.tagName === 'circle' || 
    target.tagName === 'path' ||
    target.hasAttribute('fill-opacity') || 
    (typeof target.className === 'string' && 
      (target.className.includes('glow') || target.className.includes('interactive')))
  );
  
  // 仍然选中组件，无论是否为交互元素
  if (selectedComponentId.value !== component.id) {
    selectedComponentId.value = component.id;
    emit('component-selected', component);
  }
  
  // 如果组件锁定位置或是交互元素，则不启动拖拽
  if (component.positionlock || isInteractiveElement || e.button !== 0) {
    return;
  }
  
  // 阻止事件冒泡
  e.stopPropagation();
  
  // 设置拖拽状态
  draggingComponentId.value = component.id;
  isDragging.value = false;
  isMiddleDragging.value = false;

  // 获取容器位置
  if (!canvasContainer.value) return;
  const containerRect = canvasContainer.value.getBoundingClientRect();
  
  // 计算鼠标在画布坐标系中的位置
  const mouseX_canvas = (e.clientX - containerRect.left - position.x) / scale.value;
  const mouseY_canvas = (e.clientY - containerRect.top - position.y) / scale.value;

  // 计算鼠标相对于组件左上角的偏移量
  componentDragOffset.x = mouseX_canvas - component.x;
  componentDragOffset.y = mouseY_canvas - component.y;

  // 添加全局监听器
  document.addEventListener('mousemove', onComponentDrag);
  document.addEventListener('mouseup', stopComponentDrag);
}

// 拖拽组件过程
function onComponentDrag(e: MouseEvent) {
  if (!draggingComponentId.value || !canvasContainer.value) return;

  // 防止触发组件内部的事件
  e.stopPropagation();
  e.preventDefault();

  const containerRect = canvasContainer.value.getBoundingClientRect();
  
  // 计算鼠标在画布坐标系中的位置
  const mouseX_canvas = (e.clientX - containerRect.left - position.x) / scale.value;
  const mouseY_canvas = (e.clientY - containerRect.top - position.y) / scale.value;

  // 计算组件新位置
  const newX = mouseX_canvas - componentDragOffset.x;
  const newY = mouseY_canvas - componentDragOffset.y;

  // 获取当前拖动的组件
  const draggedComponent = diagramParts.value.find(p => p.id === draggingComponentId.value);
  if (!draggedComponent) return;
  
  // 更新组件位置
  diagramData.value = updatePartPosition(diagramData.value, draggingComponentId.value, Math.round(newX), Math.round(newY));
  
  // 如果组件属于组，移动组内所有其他组件
  if (draggedComponent.group) {
    const deltaX = Math.round(newX) - draggedComponent.x;
    const deltaY = Math.round(newY) - draggedComponent.y;
    
    // 找出属于同一组但不是当前拖动组件的其他组件
    const groupComponents = diagramParts.value.filter(
      p => p.group === draggedComponent.group && p.id !== draggingComponentId.value && !p.positionlock
    );
    
    // 更新这些组件的位置
    for (const groupComp of groupComponents) {
      diagramData.value = updatePartPosition(
        diagramData.value, 
        groupComp.id, 
        groupComp.x + deltaX, 
        groupComp.y + deltaY
      );
    }
  }
  
  // 通知父组件位置已更新
  emit('component-moved', {
    id: draggingComponentId.value,
    x: Math.round(newX),
    y: Math.round(newY),
  });
  
  // 通知图表已更新
  emit('diagram-updated', diagramData.value);
}

// 停止拖拽组件
function stopComponentDrag() {
  // 如果有组件被拖拽，保存当前状态
  if (draggingComponentId.value) {
    console.log(`组件拖拽结束: ${draggingComponentId.value}`);
    
    // 保存图表数据
    saveDiagramData(diagramData.value);
    
    // 清除拖动状态
    draggingComponentId.value = null;
  }
  
  document.removeEventListener('mousemove', onComponentDrag);
  document.removeEventListener('mouseup', stopComponentDrag);
}

// 更新组件属性
function updateComponentProp(componentId: string, propName: string, value: any) {
  diagramData.value = updatePartAttribute(diagramData.value, componentId, propName, value);
  emit('diagram-updated', diagramData.value);
  saveDiagramData(diagramData.value);
}

// --- 连线操作 ---
// 更新鼠标位置
function updateMousePosition(e: MouseEvent) {
  if (!canvasContainer.value) return;
  const containerRect = canvasContainer.value.getBoundingClientRect();
  mousePosition.x = (e.clientX - containerRect.left - position.x) / scale.value;
  mousePosition.y = (e.clientY - containerRect.top - position.y) / scale.value;
}  // 处理引脚点击
function handlePinClick(componentId: string, pinInfo: any, event: MouseEvent) {
  if (!canvasContainer.value) return;
  updateMousePosition(event);
  
  if (!pinInfo || !pinInfo.label) {
    console.error('无效的针脚信息:', pinInfo);
    return;
  }
  
  // 获取引脚ID
  const pinId = pinInfo.label;
  
  console.log('----引脚点击详情开始----');
  console.log('组件ID:', componentId);
  console.log('引脚ID:', pinId);
  console.log('引脚原始信息:', pinInfo);
  console.log('鼠标位置:', mousePosition);
  
  if (!isCreatingWire.value) {
    // 开始创建连线
    const containerRect = canvasContainer.value.getBoundingClientRect();
    // 获取初始位置信息
    let pinPosition = pinInfo.position;
    console.log('Pin信息:', pinInfo);
    console.log('Pin初始位置:', pinPosition);
    console.log('组件ID:', componentId);
    console.log('引脚ID:', pinId);
    
    // 从组件引用中获取组件实例
    const component = componentRefs.value[componentId];
    console.log('组件引用:', component);
    
    // 查找组件部件对象以获取组件位置
    const componentPart = diagramParts.value.find(p => p.id === componentId);
    if (!componentPart) {
      console.error('找不到组件部件对象:', componentId);
    }
    
    // 重新设置引脚位置（初始化）
    pinPosition = { x: 0, y: 0 };
    
    // 如果组件实例存在且有 getPinPosition 方法
    if (component && typeof component.getPinPosition === 'function' && componentPart) {
      try {
        console.log('尝试从组件获取引脚位置');
        console.log('组件部件位置:', componentPart.x, componentPart.y);
        const pinRelativePos = component.getPinPosition(pinId);
        console.log('组件返回的引脚相对位置:', pinRelativePos);
        
        if (pinRelativePos) {
          // 计算引脚的绝对位置 = 组件位置 + 引脚相对位置
          pinPosition = {
            x: componentPart.x + pinRelativePos.x,
            y: componentPart.y + pinRelativePos.y
          };
          console.log('计算的引脚绝对位置:', pinPosition);
        } else {
          // 如果没有找到引脚位置，使用组件位置
          pinPosition = {
            x: componentPart.x,
            y: componentPart.y
          };
          console.log('使用组件位置:', pinPosition);
        }
      } catch (error) {
        console.error(`获取引脚位置出错:`, error);
      }
    } else if (componentPart) {
      // 如果组件不存在或没有 getPinPosition 方法，使用组件的位置
      pinPosition = {
        x: componentPart.x,
        y: componentPart.y
      };
      console.log('使用组件位置:', pinPosition);
    }
    
    console.log('最终使用的引脚位置:', pinPosition);
    
    // 使用最终的引脚位置作为连线起点
    setWireCreationStart(pinPosition.x, pinPosition.y, componentId, pinId, pinInfo.constraint);
    document.addEventListener('mousemove', onCreatingWireMouseMove);
  } else {
    // 完成连线创建
    if (componentId === creatingWireStartInfo.componentId && pinId === creatingWireStartInfo.pinId) {
      // 如果点击的是同一个引脚，取消连线创建
      cancelWireCreation();
      return;
    }
    
    // 获取终点引脚位置
    let endPosition = { x: 0, y: 0 };
    const componentPart = diagramParts.value.find(p => p.id === componentId);
    const endComponent = componentRefs.value[componentId];
    
    console.log('终点组件部件:', componentPart);
    console.log('终点组件引用:', endComponent);
    
    // 如果找到组件，设置终点位置
    if (componentPart) {
      endPosition.x = componentPart.x;
      endPosition.y = componentPart.y;
      
      // 如果组件实现了getPinPosition方法，使用它
      if (endComponent && typeof endComponent.getPinPosition === 'function') {
        try {
          const pinPos = endComponent.getPinPosition(pinId);
          console.log('终点组件返回的引脚位置:', pinPos);
          
          if (pinPos) {
            // 正确合并组件位置与引脚相对位置
            endPosition = {
              x: componentPart.x + pinPos.x,
              y: componentPart.y + pinPos.x
            };
            console.log('终点引脚位置(来自组件方法):', endPosition);
          }
        } catch (error) {
          console.error(`获取终点引脚位置出错:`, error);
        }
      } else {
        // 对于没有提供引脚精确位置的组件，使用组件位置
        console.log('终点组件没有提供引脚位置方法，使用组件位置');
      }
    } else {
      console.error('找不到终点组件部件对象:', componentId);
    }
    
    console.log('最终使用的终点位置:', endPosition);
    console.log('线路从', creatingWireStartInfo, '到', { componentId, pinId });
    console.log('----引脚点击详情结束----');
    
    // 创建新的连线
    const newConnection: ConnectionArray = [
      `${creatingWireStartInfo.componentId}:${creatingWireStartInfo.pinId}`,
      `${componentId}:${pinId}`,
      2, // 线宽
      ["right10", "*", "left10"] // 默认路径
    ];
    
    // 更新图表数据
    diagramData.value = {
      ...diagramData.value,
      connections: [...diagramData.value.connections, newConnection]
    };
    
    // 通知连线创建
    emit('wire-created', newConnection);
    emit('diagram-updated', diagramData.value);
    
    // 保存图表数据
    saveDiagramData(diagramData.value);
    
    // 重置连线创建状态
    resetWireCreation();
    document.removeEventListener('mousemove', onCreatingWireMouseMove);
  }
}

// 开始创建连线
function setWireCreationStart(x: number, y: number, componentId: string, pinId: string, constraint?: string) {
  isCreatingWire.value = true;
  creatingWireStart.x = x;
  creatingWireStart.y = y;
  creatingWireStartInfo.componentId = componentId;
  creatingWireStartInfo.pinId = pinId;
  creatingWireStartInfo.constraint = constraint || '';
}

// 重置连线创建状态
function resetWireCreation() {
  isCreatingWire.value = false;
  creatingWireStart.x = 0;
  creatingWireStart.y = 0;
  creatingWireStartInfo.componentId = '';
  creatingWireStartInfo.pinId = '';
  creatingWireStartInfo.constraint = '';
}

// 取消连线创建
function cancelWireCreation() {
  resetWireCreation();
  document.removeEventListener('mousemove', onCreatingWireMouseMove);
}

// 连线创建过程中的鼠标移动
function onCreatingWireMouseMove(e: MouseEvent) {
  updateMousePosition(e);
}

// 删除连线
function deleteWire(wireIndex: number) {
  diagramData.value = deleteConnection(diagramData.value, wireIndex);
  emit('wire-deleted', wireIndex);
  emit('diagram-updated', diagramData.value);
  saveDiagramData(diagramData.value);
}

// 删除组件
function deleteComponent(componentId: string) {
  diagramData.value = deletePart(diagramData.value, componentId);
  emit('component-delete', componentId);
  emit('diagram-updated', diagramData.value);
  saveDiagramData(diagramData.value);
  
  // 清除选中状态
  if (selectedComponentId.value === componentId) {
    selectedComponentId.value = null;
  }
}

// --- 文件操作功能 ---
// 打开文件选择器
function openDiagramFileSelector() {
  if (fileInput.value) {
    fileInput.value.click();
  }
}

// 处理文件选择
function handleFileSelected(event: Event) {
  const target = event.target as HTMLInputElement;
  const file = target.files?.[0];
  
  if (!file) {
    return;
  }
  
  // 设置加载状态
  isLoading.value = true;
  
  const reader = new FileReader();
    reader.onload = (e) => {
    try {
      // 检查组件是否仍然挂载
      if (!document.body.contains(canvasContainer.value)) {
        return; // 如果组件已经卸载，不执行后续操作
      }
      
      const content = e.target?.result as string;
      const parsed = JSON.parse(content);
      
      // 使用验证函数检查文件格式
      const validation = validateDiagramData(parsed);
      
      if (!validation.isValid) {
        showToast(`不是有效的diagram.json格式: ${validation.errors.join('; ')}`, 'error');
        isLoading.value = false;
        return;
      }
      
      // 更新画布数据
      diagramData.value = parsed as DiagramData;
      
      // 保存到本地文件
      saveDiagramData(diagramData.value);
      
      // 发出更新事件
      emit('diagram-updated', diagramData.value);
      
      showToast(`成功导入diagram文件`, 'success');
      
    } catch (error) {
      console.error('解析JSON文件出错:', error);
      if (document.body.contains(canvasContainer.value)) {
        showToast('解析文件出错，请确认是有效的JSON格式', 'error');
      }
    } finally {
      // 检查组件是否仍然挂载
      if (document.body.contains(canvasContainer.value)) {
        // 结束加载状态
        isLoading.value = false;
      }
      
      // 清除文件输入，以便同一文件可以再次导入
      target.value = '';
    }
  };
    reader.onerror = () => {
    // 检查组件是否仍然挂载
    if (document.body.contains(canvasContainer.value)) {
      showToast('读取文件时出错', 'error');
      isLoading.value = false;
    }
    // 清除文件输入
    target.value = '';
  };
  
  reader.readAsText(file);
}

// 导出当前diagram数据
function exportDiagram() {
  try {
    isLoading.value = true;
    
    // 创建一个Blob对象
    const jsonString = JSON.stringify(diagramData.value, null, 2);
    const blob = new Blob([jsonString], { type: 'application/json' });
    
    // 创建一个下载链接
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = 'diagram.json';
    a.click();
      // 释放URL对象
    const timerId = setTimeout(() => {
      URL.revokeObjectURL(url);
      // 检查组件是否仍然挂载
      if (document.body.contains(canvasContainer.value)) {
        isLoading.value = false;
        showToast('成功导出diagram文件', 'success');
      }
    }, 100);
    
    // 将定时器ID保存起来，以便在组件卸载时清除
    toastTimers.push(timerId);
  } catch (error) {
    console.error('导出diagram文件时出错:', error);
    showToast('导出diagram文件时出错', 'error');
    isLoading.value = false;
  }
}

// 显示通知
function showToast(message: string, type: 'success' | 'error' | 'info' = 'info', duration = 3000) {
  notificationMessage.value = message;
  notificationType.value = type;
  showNotification.value = true;
  
  // 保存定时器ID以便清除
  const timerId = setTimeout(() => {
    // 检查组件是否仍然挂载
    if (document.body.contains(canvasContainer.value)) {
      showNotification.value = false;
    }
  }, duration);
  
  // 将定时器ID保存起来，以便在组件卸载时清除
  toastTimers.push(timerId);
}

// --- 生命周期钩子 ---
onMounted(async () => {
  // 重置组件引用
  resetComponentRefs();
  
  // 加载图表数据
  try {
    diagramData.value = await loadDiagramData();
    
    // 预加载所有组件模块
    const componentTypes = new Set<string>();
    diagramData.value.parts.forEach(part => {
      componentTypes.add(part.type);
    });
    
    console.log('DiagramCanvas: Requesting component modules:', Array.from(componentTypes));
    
    // 通知父组件需要加载组件模块
    componentTypes.forEach(type => {
      if (!props.componentModules[type]) {
        emit('load-component-module', type);
      }
    });
  } catch (error) {
    console.error('加载图表数据失败:', error);
  }
    // 初始化中心位置
  if (canvasContainer.value) {
    // 修改为将画布中心点放在容器中心点
    position.x = canvasContainer.value.clientWidth / 2 - 5000; // 画布宽度的一半
    position.y = canvasContainer.value.clientHeight / 2 - 5000; // 画布高度的一半
  }
  
  // 添加键盘事件监听器
  window.addEventListener('keydown', handleKeyDown);
});

// 处理键盘事件
function handleKeyDown(e: KeyboardEvent) {
  // 如果当前有选中的组件，并且按下了Delete键
  if (selectedComponentId.value && (e.key === 'Delete')) {
    // 触发删除组件事件
    deleteComponent(selectedComponentId.value);
  }
  
  // 如果当前正在创建连线，并且按下了ESC键
  if (isCreatingWire.value && e.key === 'Escape') {
    // 取消连线创建
    cancelWireCreation();
  }
}

onUnmounted(() => {
  // 清理事件监听器
  document.removeEventListener('mousemove', onComponentDrag);
  document.removeEventListener('mouseup', stopComponentDrag);
  document.removeEventListener('mousemove', onDrag);
  document.removeEventListener('mouseup', stopDrag);
  document.removeEventListener('mousemove', onCreatingWireMouseMove);
  
  // 移除键盘事件监听器
  window.removeEventListener('keydown', handleKeyDown);
  
  // 清除所有toast定时器
  toastTimers.forEach(timerId => clearTimeout(timerId));
});

// --- 对外API ---
// 获取当前图表数据
function getDiagramData() {
  return diagramData.value;
}

// 设置图表数据
function setDiagramData(data: DiagramData) {
  diagramData.value = data;
  emit('diagram-updated', data);
}

// 暴露方法给父组件
defineExpose({
  // 基本数据操作
  getDiagramData: () => diagramData.value,  setDiagramData: (data: DiagramData) => {
    // 检查组件是否仍然挂载
    if (!document.body.contains(canvasContainer.value)) {
      return; // 如果组件已经卸载，不执行后续操作
    }
    
    isLoading.value = true;
    
    // 使用requestAnimationFrame确保UI更新
    window.requestAnimationFrame(() => {
      // 再次检查组件是否仍然挂载
      if (!document.body.contains(canvasContainer.value)) {
        return; // 如果组件已经卸载，不执行后续操作
      }
      
      diagramData.value = data;
      saveDiagramData(data);
      
      // 发出diagram-updated事件
      emit('diagram-updated', data);
      
      // 短暂延迟后结束加载状态，以便UI能更新
      const timerId = setTimeout(() => {
        // 检查组件是否仍然挂载
        if (document.body.contains(canvasContainer.value)) {
          isLoading.value = false;
        }
      }, 200);
      
      // 将定时器ID保存起来，以便在组件卸载时清除
      toastTimers.push(timerId);
    });
  },
  
  // 文件操作
  openDiagramFileSelector,
  exportDiagram,
  
  // 组件操作
  getSelectedComponent: () => {
    if (!selectedComponentId.value) return null;
    return diagramParts.value.find(p => p.id === selectedComponentId.value) || null;
  },
  deleteSelectedComponent: () => {
    if (selectedComponentId.value) {
      deleteComponent(selectedComponentId.value);
    }
  },
  
  // 画布状态
  getCanvasPosition: () => ({ x: position.x, y: position.y }),
  getScale: () => scale.value,
  
  // 通知系统
  showToast
});

// 监视器 - 当图表数据更改时保存
watch(diagramData, (newData) => {
  saveDiagramData(newData);
}, { deep: true });

// 当组件模块加载完成后，确保组件引用正确建立
watch(() => props.componentModules, () => {
  // 这里不需要特别处理，Vue 会自动通过 setComponentRef 函数更新引用
}, { deep: true });
</script>

<style scoped>
.diagram-container {
  position: relative;
  width: 100%;
  height: 100%;
  overflow: hidden;
  background-size: 20px 20px, 20px 20px, 100px 100px, 100px 100px;
  background-position: 0 0;
  user-select: none;
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  display: flex;
  flex-direction: column;
}

.diagram-canvas {
  position: relative;
  width: 10000px;
  height: 10000px;
  transform-origin: 0 0;
  user-select: none;
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
}

/* 连线层样式 */
.wires-layer {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  pointer-events: auto; /* 修复：允许线被点击 */
  z-index: 50;
  overflow: visible; /* 确保超出SVG范围的内容也能显示 */
}

.wires-layer path {
  pointer-events: stroke;
  cursor: pointer;
}

/* 元器件容器样式 */
.component-wrapper {
  position: absolute;
  padding: 0; /* 移除内边距，确保元素大小与内容完全匹配 */
  box-sizing: content-box; /* 使用content-box确保内容尺寸不受padding影响 */
  display: inline-block;
  overflow: visible; /* 允许内容溢出（用于显示边框） */
  cursor: move; /* 显示移动光标 */
  user-select: none;
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
}

/* 悬停状态 - 使用outline而非伪元素 */
.component-hover {
  outline: 2px dashed #3498db;
  outline-offset: 2px;
  z-index: 2;
}

/* 选中状态 - 使用outline而非伪元素 */
.component-selected {
  outline: 3px dashed;
  outline-color: #e74c3c #f39c12 #3498db #2ecc71;
  outline-offset: 3px;
}

/* 禁用状态 */
.component-disabled {
  cursor: not-allowed;
  filter: grayscale(70%);
}

/* 隐藏引脚状态 */
.component-hidepins :deep([data-pin-wrapper]) {
  display: none;
}

/* 为黑暗模式设置不同的网格线颜色 */
/* :root[data-theme="dark"] .diagram-container {
  background-image: 
    linear-gradient(to right, rgba(200, 200, 200, 0.1) 1px, transparent 1px),
    linear-gradient(to bottom, rgba(200, 200, 200, 0.1) 1px, transparent 1px),
    linear-gradient(to right, rgba(180, 180, 180, 0.15) 100px, transparent 100px),
    linear-gradient(to bottom, rgba(180, 180, 180, 0.15) 100px, transparent 100px);
} */

/* 深度选择器 - 默认阻止SVG内部元素的鼠标事件，但允许SVG本身和特定交互元素 */
.component-wrapper :deep(svg) {
  pointer-events: auto; /* 确保SVG本身可以接收鼠标事件用于拖拽 */
  user-select: none;
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
}

.component-wrapper :deep(svg *:not([class*="interactive"]):not(rect.glow):not(circle[fill-opacity]):not([fill-opacity])) {
  pointer-events: none; /* 非交互元素不接收鼠标事件 */
}

/* 允许特定SVG元素接收鼠标事件，用于交互 */
.component-wrapper :deep(svg circle[fill-opacity]),
.component-wrapper :deep(svg rect[fill-opacity]),
.component-wrapper :deep(svg rect[class*="glow"]),
.component-wrapper :deep(svg rect.glow),
.component-wrapper :deep(svg [class*="interactive"]),
.component-wrapper :deep(button),
.component-wrapper :deep(input) {
  pointer-events: auto !important;
}

.wire-active {
  stroke: #0099ff !important;
  filter: drop-shadow(0 0 4px #0099ffcc);
}
</style>
