<template>
  <div class="three-viewer">
    <div ref="container" class="canvas-container"></div>
    <div class="annotations-container" ref="annotationsContainer"></div>
    
    <!-- 调试面板 -->
    <div v-if="debugMode" class="debug-panel">
      <h3>调试模式</h3>
      <div class="debug-info">
        <p>点击模型查看部件信息</p>
        <div v-if="selectedMeshInfo">
          <p><strong>部件名称:</strong> {{ selectedMeshInfo.name || '未命名' }}</p>
          <p><strong>坐标:</strong></p>
          <pre>{{ JSON.stringify(selectedMeshInfo.position, null, 2) }}</pre>
          <button @click="copyPosition">复制坐标</button>
        </div>
      </div>
      <div class="mesh-list">
        <h4>模型部件列表:</h4>
        <ul>
          <li v-for="(mesh, index) in meshList" :key="index">
            {{ mesh.name || `未命名_${index}` }}
          </li>
        </ul>
      </div>
    </div>
  </div>
</template>

<script>
import * as THREE from 'three';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
import { CSS2DRenderer, CSS2DObject } from 'three/examples/jsm/renderers/CSS2DRenderer';
import { EffectComposer } from "three/examples/jsm/postprocessing/EffectComposer.js";
import { RenderPass } from "three/examples/jsm/postprocessing/RenderPass.js";
import { OutlinePass } from "three/examples/jsm/postprocessing/OutlinePass.js";
import { RoomEnvironment } from 'three/examples/jsm/environments/RoomEnvironment.js';

export default {
  name: 'ThreeViewerDebug',
  props: {
    modelPath: {
      type: String,
      required: true
    },
    annotations: {
      type: Array,
      default: () => []
    },
    debugMode: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      scene: null,
      camera: null,
      renderer: null,
      labelRenderer: null,
      controls: null,
      model: null,
      composer: null,
      outlinePass: null,
      frameId: null,
      sceneDomElement: null,
      annotationObjects: [],
      selectedPart: null,
      partMeshMap: {},
      meshList: [],
      selectedMeshInfo: null,
      raycaster: new THREE.Raycaster(),
      mouse: new THREE.Vector2()
    };
  },
  watch: {
    modelPath: {
      handler(v) {
        if (v) {
          this.cleanup();
          setTimeout(() => {
            this.init();
          }, 300);
        }
      },
      immediate: true
    }
  },
  mounted() {
    this.resizeObserver = new ResizeObserver(this.onWindowResize);
    this.resizeObserver.observe(this.$refs.container);
    
    // 添加点击事件
    window.addEventListener('click', this.onMouseClick, false);
  },
  beforeDestroy() {
    this.cleanup();
    window.removeEventListener('click', this.onMouseClick, false);
    if (this.resizeObserver) {
      this.resizeObserver.disconnect();
    }
  },
  methods: {
    cleanup() {
      if (this.frameId) {
        cancelAnimationFrame(this.frameId);
      }
      if (this.scene) {
        this.scene.clear();
        this.scene = null;
      }
      if (this.renderer) {
        this.renderer.dispose();
        this.renderer = null;
      }
      if (this.labelRenderer) {
        this.labelRenderer.domElement.remove();
        this.labelRenderer = null;
      }
      if (this.sceneDomElement) {
        this.sceneDomElement.innerHTML = '';
      }
    },

    init() {
      this.sceneDomElement = this.$refs.container;
      
      // 创建场景
      this.scene = new THREE.Scene();
      this.scene.background = new THREE.Color(0xf0f0f0);

      // 创建相机
      const width = this.sceneDomElement.clientWidth;
      const height = this.sceneDomElement.clientHeight;
      this.camera = new THREE.PerspectiveCamera(45, width / height, 0.1, 1000);
      this.camera.position.set(5, 5, 5);

      // WebGL渲染器
      this.renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });
      this.renderer.setPixelRatio(window.devicePixelRatio);
      this.renderer.setSize(width, height);
      this.renderer.shadowMap.enabled = true;
      this.renderer.outputEncoding = THREE.sRGBEncoding;
      this.sceneDomElement.appendChild(this.renderer.domElement);

      // CSS2D渲染器
      this.labelRenderer = new CSS2DRenderer();
      this.labelRenderer.setSize(width, height);
      this.labelRenderer.domElement.style.position = 'absolute';
      this.labelRenderer.domElement.style.top = '0';
      this.labelRenderer.domElement.style.pointerEvents = 'none';
      this.$refs.annotationsContainer.appendChild(this.labelRenderer.domElement);

      // 光照
      const ambientLight = new THREE.AmbientLight(0xffffff, 0.6);
      this.scene.add(ambientLight);

      const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8);
      directionalLight.position.set(5, 10, 5);
      directionalLight.castShadow = true;
      this.scene.add(directionalLight);

      // 环境光
      const pmremGenerator = new THREE.PMREMGenerator(this.renderer);
      const env = pmremGenerator.fromScene(new RoomEnvironment(this.renderer), 0.04).texture;
      this.scene.environment = env;

      // 控制器
      this.controls = new OrbitControls(this.camera, this.renderer.domElement);
      this.controls.enableDamping = true;
      this.controls.dampingFactor = 0.05;

      // 加载模型
      this.loadModel();

      // 开始动画
      this.animate();
    },

    loadModel() {
      const loader = new GLTFLoader();
      
      loader.load(
        this.modelPath,
        (gltf) => {
          this.model = gltf.scene;
          
          // 收集所有mesh信息
          this.partMeshMap = {};
          this.meshList = [];
          
          this.model.traverse((child) => {
            if (child.isMesh) {
              child.castShadow = true;
              child.receiveShadow = true;
              
              // 存储mesh引用
              const meshInfo = {
                name: child.name,
                mesh: child,
                parent: child.parent
              };
              
              this.meshList.push(meshInfo);
              
              if (child.name) {
                this.partMeshMap[child.name] = child;
              }
            }
          });

          console.log('模型部件列表:', this.meshList.map(m => m.name || '未命名'));
          console.log('部件映射表:', Object.keys(this.partMeshMap));

          // 计算模型边界并居中
          const box = new THREE.Box3().setFromObject(this.model);
          const center = box.getCenter(new THREE.Vector3());
          const size = box.getSize(new THREE.Vector3());
          
          this.model.position.sub(center);
          
          // 调整相机
          const maxDim = Math.max(size.x, size.y, size.z);
          const fov = this.camera.fov * (Math.PI / 180);
          let cameraZ = Math.abs(maxDim / 2 / Math.tan(fov / 2));
          cameraZ *= 2.5;
          
          this.camera.position.set(cameraZ, cameraZ, cameraZ);
          this.camera.lookAt(0, 0, 0);
          this.controls.target.set(0, 0, 0);
          
          this.scene.add(this.model);
          
          // 创建标注
          this.createAnnotations();
          
          this.$emit('model-loaded', {
            meshList: this.meshList,
            partMeshMap: Object.keys(this.partMeshMap)
          });
        },
        (progress) => {
          const percent = (progress.loaded / progress.total) * 100;
          this.$emit('loading-progress', percent);
        },
        (error) => {
          console.error('模型加载失败:', error);
          this.$emit('model-error', error);
        }
      );
    },

    createAnnotations() {
      // 清除旧标注
      this.annotationObjects.forEach(obj => {
        this.scene.remove(obj);
      });
      this.annotationObjects = [];

      this.annotations.forEach((annotation, index) => {
        // 尝试通过名称匹配找到对应的mesh
        const mesh = this.findMeshByName(annotation.name);
        
        let position = new THREE.Vector3();
        
        if (mesh) {
          // 如果找到对应mesh，使用其位置
          mesh.getWorldPosition(position);
          
          // 获取mesh的包围盒，标注放在上方
          const box = new THREE.Box3().setFromObject(mesh);
          const size = box.getSize(new THREE.Vector3());
          position.y += size.y / 2 + 0.3;
          
          console.log(`找到匹配: ${annotation.name} -> ${mesh.name}`, position);
        } else {
          // 如果没找到，使用圆形分布
          const radius = 2;
          const angleStep = (Math.PI * 2) / this.annotations.length;
          const angle = angleStep * index;
          position.set(
            Math.cos(angle) * radius,
            1 + Math.sin(index) * 0.5,
            Math.sin(angle) * radius
          );
          
          console.warn(`未找到匹配: ${annotation.name}，使用默认位置`);
        }

        // 创建标注标签
        const labelDiv = document.createElement('div');
        labelDiv.className = 'annotation-label';
        labelDiv.textContent = `${index + 1} ${annotation.name}`;
        labelDiv.style.cssText = `
          background: rgba(64, 158, 255, 0.9);
          color: white;
          padding: 5px 10px;
          border-radius: 4px;
          font-size: 12px;
          cursor: pointer;
          white-space: nowrap;
          pointer-events: auto;
          box-shadow: 0 2px 4px rgba(0,0,0,0.2);
        `;
        
        labelDiv.addEventListener('click', () => {
          this.onAnnotationClick(annotation, index, mesh);
        });

        const label = new CSS2DObject(labelDiv);
        label.position.copy(position);
        label.userData = { annotation, index, mesh };
        
        this.scene.add(label);
        this.annotationObjects.push(label);

        // 创建连接线
        if (mesh) {
          const meshPos = new THREE.Vector3();
          mesh.getWorldPosition(meshPos);
          
          const points = [meshPos, position];
          const geometry = new THREE.BufferGeometry().setFromPoints(points);
          const material = new THREE.LineBasicMaterial({ 
            color: 0x409eff,
            transparent: true,
            opacity: 0.6
          });
          const line = new THREE.Line(geometry, material);
          this.scene.add(line);
          this.annotationObjects.push(line);
        }
      });
    },

    findMeshByName(annotationName) {
      // 精确匹配
      if (this.partMeshMap[annotationName]) {
        return this.partMeshMap[annotationName];
      }
      
      // 模糊匹配
      for (let meshName in this.partMeshMap) {
        if (meshName.includes(annotationName) || annotationName.includes(meshName)) {
          return this.partMeshMap[meshName];
        }
      }
      
      // 尝试匹配关键词
      const keywords = annotationName.split(/[，、\s]+/);
      for (let keyword of keywords) {
        if (keyword.length > 1) {
          for (let meshName in this.partMeshMap) {
            if (meshName.includes(keyword)) {
              return this.partMeshMap[meshName];
            }
          }
        }
      }
      
      return null;
    },

    onAnnotationClick(annotation, index, mesh) {
      this.highlightPart(index, mesh);
      this.$emit('annotation-click', annotation, index);
    },

    highlightPart(index, mesh) {
      // 重置之前的高亮
      this.annotationObjects.forEach((obj) => {
        if (obj.isLine) {
          obj.material.opacity = 0.6;
          obj.material.color.setHex(0x409eff);
        } else if (obj.element) {
          obj.element.style.background = 'rgba(64, 158, 255, 0.9)';
          obj.element.style.transform = 'scale(1)';
        }
      });

      // 高亮选中的标注
      this.selectedPart = index;
      this.annotationObjects.forEach((obj, i) => {
        const objIndex = Math.floor(i / 2);
        if (objIndex === index) {
          if (obj.isLine) {
            obj.material.opacity = 1;
            obj.material.color.setHex(0xff6b00);
          } else if (obj.element) {
            obj.element.style.background = 'rgba(255, 107, 0, 0.95)';
            obj.element.style.transform = 'scale(1.1)';
          }
        }
      });

      // 高亮3D部件
      if (mesh) {
        this.highlightMesh(mesh);
      }
    },

    highlightMesh(mesh) {
      // 创建高亮效果
      if (!this.composer) {
        this.composer = new EffectComposer(this.renderer);
        const renderPass = new RenderPass(this.scene, this.camera);
        this.composer.addPass(renderPass);
        
        this.outlinePass = new OutlinePass(
          new THREE.Vector2(this.sceneDomElement.clientWidth, this.sceneDomElement.clientHeight),
          this.scene,
          this.camera
        );
        this.outlinePass.edgeStrength = 5.0;
        this.outlinePass.edgeGlow = 0.5;
        this.outlinePass.edgeThickness = 2.0;
        this.outlinePass.pulsePeriod = 2;
        this.outlinePass.visibleEdgeColor.set(0xff6b00);
        this.composer.addPass(this.outlinePass);
      }
      
      this.outlinePass.selectedObjects = [mesh.parent || mesh];
    },

    onMouseClick(event) {
      if (!this.debugMode || !this.sceneDomElement) return;

      const rect = this.sceneDomElement.getBoundingClientRect();
      this.mouse.x = ((event.clientX - rect.left) / rect.width) * 2 - 1;
      this.mouse.y = -((event.clientY - rect.top) / rect.height) * 2 + 1;

      this.raycaster.setFromCamera(this.mouse, this.camera);
      const intersects = this.raycaster.intersectObjects(this.model.children, true);

      if (intersects.length > 0) {
        const mesh = intersects[0].object;
        const point = intersects[0].point;
        
        this.selectedMeshInfo = {
          name: mesh.name,
          position: {
            x: parseFloat(point.x.toFixed(3)),
            y: parseFloat(point.y.toFixed(3)),
            z: parseFloat(point.z.toFixed(3))
          }
        };
        
        console.log('点击的部件:', this.selectedMeshInfo);
      }
    },

    copyPosition() {
      if (this.selectedMeshInfo) {
        const text = JSON.stringify(this.selectedMeshInfo.position, null, 2);
        navigator.clipboard.writeText(text).then(() => {
          this.$message.success('坐标已复制到剪贴板');
        });
      }
    },

    animate() {
      this.frameId = requestAnimationFrame(this.animate);
      
      if (this.controls) {
        this.controls.update();
      }

      if (this.renderer && this.scene && this.camera) {
        if (this.composer && this.outlinePass && this.outlinePass.selectedObjects.length > 0) {
          this.composer.render();
        } else {
          this.renderer.render(this.scene, this.camera);
        }
      }

      if (this.labelRenderer && this.scene && this.camera) {
        this.labelRenderer.render(this.scene, this.camera);
      }
    },

    onWindowResize() {
      if (this.camera && this.renderer && this.sceneDomElement) {
        const width = this.sceneDomElement.clientWidth;
        const height = this.sceneDomElement.clientHeight;
        
        this.camera.aspect = width / height;
        this.camera.updateProjectionMatrix();
        
        this.renderer.setSize(width, height);
        this.labelRenderer.setSize(width, height);
        
        if (this.composer) {
          this.composer.setSize(width, height);
        }
      }
    }
  }
}
</script>

<style scoped>
.three-viewer {
  width: 100%;
  height: 100%;
  position: relative;
}

.canvas-container {
  width: 100%;
  height: 100%;
}

.annotations-container {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

.debug-panel {
  position: absolute;
  top: 10px;
  right: 10px;
  background: rgba(255, 255, 255, 0.95);
  padding: 15px;
  border-radius: 8px;
  max-width: 300px;
  max-height: 80%;
  overflow-y: auto;
  box-shadow: 0 2px 8px rgba(0,0,0,0.2);
  pointer-events: auto;
}

.debug-panel h3 {
  margin: 0 0 10px 0;
  font-size: 16px;
  color: #303133;
}

.debug-panel h4 {
  margin: 10px 0 5px 0;
  font-size: 14px;
  color: #606266;
}

.debug-info {
  margin-bottom: 15px;
  padding-bottom: 15px;
  border-bottom: 1px solid #dcdfe6;
}

.debug-info p {
  margin: 5px 0;
  font-size: 13px;
  color: #606266;
}

.debug-info pre {
  background: #f5f7fa;
  padding: 8px;
  border-radius: 4px;
  font-size: 12px;
  margin: 5px 0;
}

.debug-info button {
  margin-top: 8px;
  padding: 5px 12px;
  background: #409eff;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  font-size: 12px;
}

.debug-info button:hover {
  background: #66b1ff;
}

.mesh-list ul {
  margin: 0;
  padding-left: 20px;
  max-height: 300px;
  overflow-y: auto;
}

.mesh-list li {
  font-size: 12px;
  color: #606266;
  margin: 3px 0;
  word-break: break-all;
}
</style>
