<template>
  <div class="three-d-map-container">
    <div 
      ref="mapContainer" 
      class="map-canvas"
      :style="{ width: '100%', height: height + 'px' }"
    ></div>
    
    <RegionDetail 
      :visible="showRegionDetail" 
      :region-data="selectedRegionData"
      @close="closeRegionDetail"
    />
  </div>
</template>

<script>
import { ref, onMounted, onBeforeUnmount, watch } from 'vue';
import * as THREE from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
import RegionDetail from './RegionDetail.vue';
import { fetchRegionDetail } from '@/services/dashboard.js';

export default {
  name: 'ThreeDMap',
  components: {
    RegionDetail
  },
  props: {
    height: {
      type: Number,
      default: 500
    },
    // 锡林郭勒盟的中心坐标
    center: {
      type: Array,
      default: () => [116.08, 43.95] // 锡林浩特市
    },
    // 地图数据
    mapData: {
      type: Array,
      default: () => []
    }
  },
  setup(props) {
    const mapContainer = ref(null);
    const showRegionDetail = ref(false);
    const selectedRegionData = ref({});
    let scene, camera, renderer, controls;
    let animationId = null;
    let landmarks = [];
    let raycaster, mouse;

    // 初始化3D场景
    const initScene = () => {
      // 创建场景
      scene = new THREE.Scene();
      scene.background = new THREE.Color(0x0a1929);
      scene.fog = new THREE.Fog(0x0a1929, 1000, 5000);

      // 创建相机
      camera = new THREE.PerspectiveCamera(
        45, 
        mapContainer.value.clientWidth / mapContainer.value.clientHeight, 
        1, 
        10000
      );
      camera.position.set(0, 500, 1000);

      // 创建渲染器
      renderer = new THREE.WebGLRenderer({ antialias: true });
      renderer.setSize(
        mapContainer.value.clientWidth, 
        mapContainer.value.clientHeight
      );
      renderer.setPixelRatio(window.devicePixelRatio);
      renderer.shadowMap.enabled = true;
      mapContainer.value.appendChild(renderer.domElement);

      // 添加光源
      const ambientLight = new THREE.AmbientLight(0x404040, 1);
      scene.add(ambientLight);

      const directionalLight = new THREE.DirectionalLight(0xffffff, 1);
      directionalLight.position.set(1, 1, 1).normalize();
      directionalLight.castShadow = true;
      scene.add(directionalLight);

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

      // 初始化射线检测器
      raycaster = new THREE.Raycaster();
      mouse = new THREE.Vector2();

      // 添加事件监听
      renderer.domElement.addEventListener('click', onMouseClick, false);
      renderer.domElement.addEventListener('mousemove', onMouseMove, false);

      // 创建地形和地标
      createTerrain();
      createLandmarks();

      // 开始渲染循环
      animate();
    };

    // 创建地形
    const createTerrain = () => {
      // 创建一个简单的平面作为地形基础
      const geometry = new THREE.PlaneGeometry(2000, 2000, 50, 50);
      const material = new THREE.MeshStandardMaterial({ 
        color: 0x2c5364,
        wireframe: false,
        transparent: true,
        opacity: 0.7
      });
      
      const terrain = new THREE.Mesh(geometry, material);
      terrain.rotation.x = -Math.PI / 2;
      terrain.position.y = -20;
      terrain.receiveShadow = true;
      scene.add(terrain);

      // 添加一些起伏效果
      const vertices = geometry.attributes.position.array;
      for (let i = 0; i < vertices.length; i += 3) {
        // 添加随机高度变化
        vertices[i + 2] = (Math.random() - 0.5) * 100;
      }
      geometry.attributes.position.needsUpdate = true;
      geometry.computeVertexNormals();
    };

    // 创建地标
    const createLandmarks = () => {
      // 清除现有的地标
      landmarks.forEach(landmark => {
        scene.remove(landmark.mesh);
        scene.remove(landmark.label);
      });
      landmarks = [];

      // 根据传入的地图数据创建地标
      props.mapData.forEach((location, index) => {
        // 计算位置（基于锡林浩特市为中心点）
        const x = (location.coordinates[0] - props.center[0]) * 5000;
        const z = (props.center[1] - location.coordinates[1]) * 5000;
        
        // 根据牛只数量确定地标大小
        const size = Math.max(20, Math.min(50, (location.cattle_count || location.cattleCount) / 1000));
        const height = Math.max(30, Math.min(100, (location.cattle_count || location.cattleCount) / 500));
        
        // 创建地标圆柱体
        const geometry = new THREE.CylinderGeometry(size, size, height, 32);
        const material = new THREE.MeshStandardMaterial({ 
          color: getColorByCattleCount(location.cattle_count || location.cattleCount),
          transparent: true,
          opacity: 0.8
        });
        const cylinder = new THREE.Mesh(geometry, material);
        cylinder.position.set(x, height/2 - 20, z);
        cylinder.castShadow = true;
        cylinder.userData = { location }; // 保存位置信息用于点击检测
        scene.add(cylinder);

        // 添加地标名称和数据
        const label = addLabel(
          `${location.name}\n牛只: ${location.cattle_count || location.cattleCount}\n牧场: ${location.farm_count || location.farmCount}`, 
          [x, height + 20, z], 
          getColorByCattleCount(location.cattle_count || location.cattleCount)
        );
        
        landmarks.push({
          mesh: cylinder,
          label: label,
          data: location
        });
      });
    };

    // 根据牛只数量获取颜色
    const getColorByCattleCount = (count) => {
      if (count > 20000) return 0x4CAF50; // 绿色 - 数量多
      if (count > 15000) return 0xFFEB3B; // 黄色 - 数量中等
      return 0xF44336; // 红色 - 数量较少
    };

    // 添加标签
    const addLabel = (text, position, color) => {
      // 创建简单的文本标签
      const canvas = document.createElement('canvas');
      const context = canvas.getContext('2d');
      canvas.width = 512;
      canvas.height = 256;
      
      context.fillStyle = `#${new THREE.Color(color).getHexString()}`;
      context.font = '24px Microsoft YaHei';
      context.textAlign = 'center';
      context.textBaseline = 'middle';
      
      // 支持多行文本
      const lines = text.split('\n');
      lines.forEach((line, i) => {
        context.fillText(line, 256, 128 + (i - (lines.length-1)/2) * 30);
      });
      
      const texture = new THREE.CanvasTexture(canvas);
      const material = new THREE.SpriteMaterial({ map: texture, transparent: true });
      const sprite = new THREE.Sprite(material);
      sprite.position.set(position[0], position[1], position[2]);
      sprite.scale.set(200, 100, 1);
      scene.add(sprite);
      return sprite;
    };

    // 鼠标点击事件处理
    const onMouseClick = async (event) => {
      // 计算鼠标位置标准化设备坐标 (-1 到 +1)
      const rect = renderer.domElement.getBoundingClientRect();
      mouse.x = ((event.clientX - rect.left) / rect.width) * 2 - 1;
      mouse.y = -((event.clientY - rect.top) / rect.height) * 2 + 1;

      // 通过摄像机和鼠标位置更新射线
      raycaster.setFromCamera(mouse, camera);

      // 计算物体和射线的交点
      const intersects = raycaster.intersectObjects(scene.children);

      for (let i = 0; i < intersects.length; i++) {
        if (intersects[i].object.userData.location) {
          const region = intersects[i].object.userData.location;
          selectedRegionData.value = await fetchRegionDetail(region.id);
          showRegionDetail.value = true;
          highlightRegion(intersects[i].object);
          break;
        }
      }
    };

    // 鼠标移动事件处理（悬停效果）
    const onMouseMove = (event) => {
      // 计算鼠标位置标准化设备坐标 (-1 到 +1)
      const rect = renderer.domElement.getBoundingClientRect();
      mouse.x = ((event.clientX - rect.left) / rect.width) * 2 - 1;
      mouse.y = -((event.clientY - rect.top) / rect.height) * 2 + 1;

      // 通过摄像机和鼠标位置更新射线
      raycaster.setFromCamera(mouse, camera);

      // 计算物体和射线的交点
      const intersects = raycaster.intersectObjects(scene.children);

      // 重置所有地标的颜色
      resetRegionColors();

      // 高亮显示悬停的地標
      for (let i = 0; i < intersects.length; i++) {
        if (intersects[i].object.userData.location) {
          intersects[i].object.material.emissive = new THREE.Color(0x222222);
          break;
        }
      }
    };

    // 高亮选中区域
    const highlightRegion = (mesh) => {
      resetRegionColors();
      mesh.material.emissive = new THREE.Color(0x333333);
    };

    // 重置区域颜色
    const resetRegionColors = () => {
      scene.children.forEach(child => {
        if (child.isMesh && child.userData.location) {
          child.material.emissive = new THREE.Color(0x000000);
        }
      });
    };

    // 关闭区域详情
    const closeRegionDetail = () => {
      showRegionDetail.value = false;
      selectedRegionData.value = {};
      resetRegionColors();
    };

    // 动画循环
    const animate = () => {
      animationId = requestAnimationFrame(animate);
      
      // 更新控制器
      controls.update();
      
      // 渲染场景
      renderer.render(scene, camera);
    };

    // 窗口大小改变时调整渲染器大小
    const onWindowResize = () => {
      if (mapContainer.value) {
        camera.aspect = mapContainer.value.clientWidth / mapContainer.value.clientHeight;
        camera.updateProjectionMatrix();
        renderer.setSize(
          mapContainer.value.clientWidth, 
          mapContainer.value.clientHeight
        );
      }
    };

    // 监听地图数据变化
    watch(() => props.mapData, () => {
      if (scene) {
        createLandmarks();
      }
    }, { deep: true });

    // 清理资源
    const cleanup = () => {
      if (animationId) {
        cancelAnimationFrame(animationId);
      }
      
      if (renderer) {
        renderer.domElement.removeEventListener('click', onMouseClick, false);
        renderer.domElement.removeEventListener('mousemove', onMouseMove, false);
        mapContainer.value.removeChild(renderer.domElement);
        renderer.dispose();
      }
      
      if (controls) {
        controls.dispose();
      }
      
      // 清理场景中的所有对象
      if (scene) {
        while(scene.children.length > 0) { 
          scene.remove(scene.children[0]); 
        }
      }
    };

    onMounted(() => {
      initScene();
      window.addEventListener('resize', onWindowResize);
    });

    onBeforeUnmount(() => {
      window.removeEventListener('resize', onWindowResize);
      cleanup();
    });

    return {
      mapContainer,
      showRegionDetail,
      selectedRegionData,
      closeRegionDetail
    };
  }
};
</script>

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

.map-canvas {
  width: 100%;
  height: 100%;
  display: block;
}
</style>