<template>
    <!-- 进度条 -->
    <!-- <el-progress
      :percentage="progress"
      :status="progress === 100 ? 'success' : ''"
      :stroke-width="10"
      :text-inside="true"
      style="width: 100%; margin-bottom: 20px;"
    /> -->
  <div ref="threeContainer" class="three-container" :style="{height: height}">
    <!-- 添加色卡Canvas -->
    <canvas 
      v-if="showColorCard" 
      ref="colorCardCanvas" 
      class="color-card-canvas"
      :style="colorCardStyle"
    ></canvas>
  </div>
</template>

<script setup>
import { ref, onMounted, onUnmounted, watch } from "vue"
import * as THREE from "three"
import { VTKParserFactory } from "@views/threejsView/utils/parsers/VTKParserFactory"
import { UnstructuredGridRenderer } from "@views/threejsView/utils/renderers/UnstructuredGridRenderer"
import { PolyDataRenderer } from "@views/threejsView/utils/renderers/PolyDataRenderer"
import { xyzDataRenderer } from "@views/threejsView/utils/renderers/xyzDataRenderer"
import { bdfDataRenderer } from "@views/threejsView/utils/renderers/bdfDataRenderer"
import { CgnsJSONRenderer } from "@views/threejsView/utils/renderers/CgnsJSONRenderer";
import { PltDataRenderer } from "@views/threejsView/utils/renderers/pltDataRenderer";
import {
  initScene,
  initCamera,
  initRenderer,
  animateScene,
  cleanupScene,
  initControls,
  createAxesHelper
} from "../utils/threeUtils"

const props = defineProps({
  data: {
    type: Object,
    required: true
  },
  height: {
    type: String,
    required: true
  }
})

const threeContainer = ref(null);
const colorCardCanvas = ref(null)
const colorCardContext = ref(null)
const progress = ref(0); // 进度条的值

let scene, camera, renderer, controls

// 初始化场景
const init = () => {
  scene = initScene();
  camera = initCamera();
  renderer = initRenderer(threeContainer.value);
  controls = initControls(camera, renderer);
  // createAxesHelper(scene); // 添加坐标轴指示器
}

// 更新进度
const updateProgress = (current, total) => {
  progress.value = Math.floor((current / total) * 100);
};

const adjustCameraToFit = (scene, camera) => {
  const box = new THREE.Box3().setFromObject(scene)
  const size = new THREE.Vector3()
  box.getSize(size)

  const maxDim = Math.max(size.x, size.y, size.z)
  const fov = camera.fov * (Math.PI / 180)
  let cameraZ = Math.abs(maxDim / Math.sin(fov / 2))

  const center = new THREE.Vector3()
  box.getCenter(center)
  camera.position.set(center.x, center.y, cameraZ)
  camera.lookAt(center)
}

// 渲染 VTK 数据
const renderVTK = (data) => {
  if (!data) return
  // 根据文件格式选择解析器
  const parser = VTKParserFactory.createParser(data.data.datasetType)
  const parsedData = parser.parse(data)

  // 根据文件格式选择渲染器
  let dataRenderer
  switch (data.data.datasetType) {
    case "UNSTRUCTURED_GRID":
      dataRenderer = new UnstructuredGridRenderer()
      break;
    case "POLYDATA":
      dataRenderer = new PolyDataRenderer()
      break;
    case "xyz":
      dataRenderer = new xyzDataRenderer()
      break;
    case "bdf":
      dataRenderer = new bdfDataRenderer(updateProgress,() => {
        // 渲染完成后的回调
        adjustCameraForBdf(scene, camera);
      })
      break;
    case "cgns":
      dataRenderer = new CgnsJSONRenderer(updateProgress, () => {
      adjustCameraForCgns(scene, camera);
      });
      break;
    case "plt":
      dataRenderer = new PltDataRenderer(updateProgress, () => {
      adjustCameraForPlt(scene, camera);
      });
      break;
    default:
      console.log("11111")
      
  }
  // 渲染数据
  dataRenderer.render(parsedData, scene)

  // 根据数据类型调整相机位置
  if (data.datasetType === "UNSTRUCTURED_GRID") {
    adjustCameraForUnstructuredGrid(scene, camera);
    return;
  }
  if (data.datasetType === "POLYDATA") {
    adjustCameraForPolydata(scene, camera);
    return;
  }
  if (data.data.datasetType === "xyz"){
    adjustCameraForXYZ(scene, camera);
    return;
  }
  if (data.data.datasetType === "bdf"){
    adjustCameraForBdf(scene, camera);
    return;
  }
  if (data.data.datasetType === "cgns"){
    adjustCameraForCgns(scene, camera);
    return;
  }

  if (data.data.datasetType === "plt"){
    adjustCameraForPlt(scene, camera);
    return;
  }

}

// 计算色卡显示状态和样式
const showColorCard = computed(() => {
  return props.data?.config?.colorCard?.visible
})

const colorCardStyle = computed(() => {
  if (!showColorCard.value) return {}
  const config = props.data.config.colorCard
  return {
    position: 'absolute',
    [config.orientation === 'vertical' ? 'right' : 'bottom']: '10px',
    [config.orientation === 'vertical' ? 'top' : 'left']: '50%',
    transform: config.orientation === 'vertical' 
      ? 'translateY(-50%)' 
      : 'translateX(-50%)',
    width: config.orientation === 'vertical' 
      ? `${config.width * 100}px` 
      : `${config.width * 100}%`,
    height: config.orientation === 'vertical' 
      ? `${config.height * 100}%` 
      : `${config.height * 100}px`,
    zIndex: 1000
  }
})
// 初始化色卡
const initColorCard = () => {
  if (!colorCardCanvas.value) return
  colorCardContext.value = colorCardCanvas.value.getContext('2d')
  renderColorCard()
}

// 渲染色卡
const renderColorCard = () => {
  if (!showColorCard.value || !colorCardContext.value) return
  
  const config = props.data.config.colorCard
  const ctx = colorCardContext.value
  const width = colorCardCanvas.value.width
  const height = colorCardCanvas.value.height
  
  // 清除画布
  ctx.clearRect(0, 0, width, height)
  
  // 创建渐变
  let gradient
  if (config.orientation === 'vertical') {
    gradient = ctx.createLinearGradient(0, height, 0, 0)
  } else {
    gradient = ctx.createLinearGradient(0, 0, width, 0)
  }
  
  // 添加色卡颜色
  gradient.addColorStop(0, '#0000ff') // 蓝色
  gradient.addColorStop(0.5, '#00ff00') // 绿色
  gradient.addColorStop(1, '#ff0000') // 红色
  
  // 填充渐变
  ctx.fillStyle = gradient
  ctx.fillRect(0, 0, width, height)
  
  // 添加刻度
  ctx.strokeStyle = '#000'
  ctx.lineWidth = 1
  ctx.font = `${config.fontSize}px ${config.font}`
  ctx.fillStyle = '#000'
  
  // 根据朝向绘制刻度
  if (config.orientation === 'vertical') {
    // 垂直色卡刻度
    const step = height / 10
    for (let i = 0; i <= 10; i++) {
      const y = i * step
      ctx.beginPath()
      ctx.moveTo(width * 0.7, y)
      ctx.lineTo(width, y)
      ctx.stroke()
      
      // 跳过指定层级的标签
      if (i % (config.skipLevels + 1) === 0) {
        const value = (1 - i / height * 1).toFixed(config.precision)
        ctx.fillText(value, 5, y + 5)
      }
    }
  } else {
    // 水平色卡刻度
    const step = width / 10
    for (let i = 0; i <= 10; i++) {
      const x = i * step
      ctx.beginPath()
      ctx.moveTo(x, 0)
      ctx.lineTo(x, height * 0.3)
      ctx.stroke()
      
      // 跳过指定层级的标签
      if (i % (config.skipLevels + 1) === 0) {
        const value = (i / width * 1).toFixed(config.precision)
        ctx.fillText(value, x - 10, height - 5)
      }
    }
  }
  
  // 添加标题
  if (config.showTitle) {
    ctx.font = `bold ${config.titleFontSize}px ${config.titleFont}`
    ctx.textAlign = 'center'
    const title = config.titleSource === 'custom' 
      ? config.customTitle 
      : 'Color Scale'
    
    if (config.orientation === 'vertical') {
      ctx.save()
      ctx.translate(20, height / 2)
      ctx.rotate(-Math.PI / 2)
      ctx.fillText(title, 0, 0)
      ctx.restore()
    } else {
      ctx.fillText(title, width / 2, height - 15)
    }
  }
}

// 监听 data 变化
watch(
  () => props.data,
  (newData) => {
    if (showColorCard.value) {
      nextTick(() => {
        initColorCard()
      })
    }
    if (newData) {
      // 清空场景
      while (scene.children.length > 0) {
        scene.remove(scene.children[0])
      }

      // 重置进度
      progress.value = 0;

      // 重新渲染 VTK 数据
      renderVTK(newData)
    }
  },
  { immediate: true }
)

// VTK 数据
onMounted(() => {
  nextTick(() => {
    init()
    if (showColorCard.value) {
      initColorCard()
    }
    animateScene(scene, camera, renderer, controls)
    // 监听窗口大小变化
    window.addEventListener("resize", onWindowResize)
  })
})
onUnmounted(() => {
  // 清理场景
  cleanupScene(renderer)
  // 移除窗口大小变化监听器
  window.removeEventListener("resize", onWindowResize)
})

const onWindowResize = () => {
  const width = threeContainer.value.clientWidth
  const height = threeContainer.value.clientHeight
  camera.aspect = width / height
  camera.updateProjectionMatrix()
  renderer.setSize(width, height)
}

const adjustCameraForUnstructuredGrid = (scene, camera) => {
  const box = new THREE.Box3().setFromObject(scene)
  const size = new THREE.Vector3()
  box.getSize(size)

  const maxDim = Math.max(size.x, size.y, size.z)
  const fov = camera.fov * (Math.PI / 180)
  let cameraZ = Math.abs(maxDim / Math.sin(fov / 2))

  const center = new THREE.Vector3()
  box.getCenter(center)
  camera.position.set(center.x, center.y, cameraZ)
  camera.lookAt(center)
}

const adjustCameraForPolydata = (scene, camera) => {
  const box = new THREE.Box3().setFromObject(scene)
  // 手动设置边界框
  box.set(new THREE.Vector3(-100, -100, -100), new THREE.Vector3(100, 100, 100))
  const size = new THREE.Vector3()
  box.getSize(size)

  console.log("Polydata bounding box:", box)
  console.log("Polydata size:", size)

  const maxDim = Math.max(size.x, size.y, size.z)
  const fov = camera.fov * (Math.PI / 180)
  let cameraZ = Math.abs(maxDim / Math.sin(fov / 2))

  const center = new THREE.Vector3()
  box.getCenter(center)
  camera.position.set(center.x, center.y, cameraZ * 0.8) // 调整相机距离
  camera.lookAt(center)
}

const adjustCameraForXYZ = (scene, camera) => {
  // 计算场景的边界框
  const box = new THREE.Box3().setFromObject(scene);

  // 获取边界框的尺寸
  const size = new THREE.Vector3();
  box.getSize(size);

  console.log("XYZ bounding box:", box);
  console.log("XYZ size:", size);

  // 计算最大尺寸
  const maxDim = Math.max(size.x, size.y, size.z);

  // 计算相机的距离
  const fov = camera.fov * (Math.PI / 180); // 将相机的视野角度转换为弧度
  let cameraZ = Math.abs(maxDim / Math.sin(fov / 2)); // 根据视野角度和最大尺寸计算相机距离

  // 获取边界框的中心点
  const center = new THREE.Vector3();
  box.getCenter(center);

  // 设置相机位置
  camera.position.set(center.x, center.y, cameraZ * 0.4); // 调整相机距离（可以根据需要调整倍数）
  camera.lookAt(center); // 让相机看向场景中心
  camera.updateProjectionMatrix(); // 更新相机的投影矩阵
};

/**
 * 调整相机位置以适应BDF数据
 * @param {THREE.Scene} scene - Three.js场景
 * @param {THREE.PerspectiveCamera} camera - 透视相机
 */
const adjustCameraForBdf = (scene, camera) => {
  // 添加环境光（均匀照亮整个场景）
  const ambientLight = new THREE.AmbientLight(0xffffff, 0.5);
  scene.add(ambientLight);

  // 添加平行光（模拟太阳光）
  const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8);
  directionalLight.position.set(1, 1, 1);
  scene.add(directionalLight);
  // 计算场景的边界框
  const box = new THREE.Box3().setFromObject(scene);

  // 获取边界框的尺寸
  const size = new THREE.Vector3();
  box.getSize(size);

  console.log("BDF bounding box:", box);
  console.log("BDF size:", size);

  // 计算最大尺寸
  const maxDim = Math.max(size.x, size.y, size.z);

  // 计算相机的距离
  const fov = camera.fov * (Math.PI / 180); // 将相机的视野角度转换为弧度
  let cameraZ = Math.abs(maxDim / Math.sin(fov / 2)); // 根据视野角度和最大尺寸计算相机距离

  // 获取边界框的中心点
  const center = new THREE.Vector3();
  box.getCenter(center);

  // 设置相机位置
  camera.position.set(center.x, center.y, cameraZ * 0.8); // 调整相机距离（可以根据需要调整倍数）
  camera.lookAt(center); // 让相机看向场景中心
  camera.updateProjectionMatrix(); // 更新相机的投影矩阵
};

/**
 * 调整相机位置以适应 JSON 数据
 * @param {THREE.Scene} scene - Three.js场景
 * @param {THREE.PerspectiveCamera} camera - 透视相机
 */
const adjustCameraForCgns = (scene, camera) => {

  // 添加环境光（均匀照亮整个场景）
  const ambientLight = new THREE.AmbientLight(0xffffff, 0.5);
  scene.add(ambientLight);

  // 添加平行光（模拟太阳光）
  const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8);
  directionalLight.position.set(1, 1, 1);
  scene.add(directionalLight);
  // 计算场景的边界框
  const box = new THREE.Box3().setFromObject(scene);

  // 获取边界框的尺寸
  const size = new THREE.Vector3();
  box.getSize(size);

  console.log("JSON bounding box:", box);
  console.log("JSON size:", size);

  // 计算最大尺寸
  const maxDim = Math.max(size.x, size.y, size.z);

  // 根据场景尺寸动态调整视野角度
  const dynamicFov = Math.min(75, 45 + (maxDim / 10)); // 动态调整 fov，确保场景大小合适
  camera.fov = dynamicFov;
  camera.updateProjectionMatrix();

  // 计算相机的距离
  const fov = camera.fov * (Math.PI / 180); // 将相机的视野角度转换为弧度
  let cameraZ = Math.abs(maxDim / Math.sin(fov / 2)); // 根据视野角度和最大尺寸计算相机距离

  // 获取边界框的中心点
  const center = new THREE.Vector3();
  box.getCenter(center);

  // 设置相机位置
  camera.position.set(center.x, center.y, cameraZ * 0.8); // 调整相机距离（可以根据需要调整倍数）
  camera.lookAt(center); // 让相机看向场景中心
  camera.updateProjectionMatrix(); // 更新相机的投影矩阵

  console.log("Adjusted camera position:", camera.position);
  console.log("Adjusted camera fov:", camera.fov);
};

/**
 * 调整相机位置和参数，使整个PLT模型在视图中可见
 * @param {THREE.Scene} scene - Three.js场景对象
 * @param {THREE.PerspectiveCamera} camera - 透视相机
 * @param {number} [paddingFactor] - 视图边距系数(1.0表示紧贴边界)
 */
const adjustCameraForPlt = (scene, camera, params = {}) => {
    const {
        padding = 2.0,
        forceTopView = false
    } = params;

    // 1. 确保场景和相机已初始化
    if (!scene || !camera) {
        console.error('场景或相机未初始化');
        return;
    }

    // 2. 计算包围盒（包含可见网格）
    const box = new THREE.Box3();
    const visibleMeshes = [];
    
    scene.traverse(child => {
        if (child.isMesh && child.visible) {
            if (!child.geometry.boundingBox) {
                child.geometry.computeBoundingBox();
            }
            box.union(child.geometry.boundingBox);
            visibleMeshes.push(child);
        }
    });

    // 3. 处理空场景情况
    if (visibleMeshes.length === 0) {
        console.warn('没有可见网格，使用默认视角');
        camera.position.set(0, 10, 0);
        camera.lookAt(0, 0, 0);
        return;
    }

    // 4. 计算模型参数
    const size = box.getSize(new THREE.Vector3());
    const center = box.getCenter(new THREE.Vector3());
    const maxDim = Math.max(size.x, size.y, size.z);
    const distance = padding * maxDim;

    // 5. 设置相机位置（根据模型特征优化）
    if (forceTopView || size.y > size.x * 1.5) {
        // 高模型或强制顶视图
        camera.position.set(
            center.x,
            center.y + distance * 1.5,
            center.z
        );
        camera.up.set(0, 0, 1); // Z轴朝上
    } else {
        // 常规模型
        camera.position.set(
            center.x + distance * 0.7,
            center.y + distance * 0.5,
            center.z + distance * 0.7
        );
        camera.up.set(0, 1, 0); // Y轴朝上
    }

    // 6. 确保相机看向中心点
    camera.lookAt(center);
    camera.near = 0.1 * maxDim; // 动态调整近平面
    camera.far = 100 * maxDim;   // 动态调整远平面
    camera.updateProjectionMatrix();

    // 7. 打印调试信息
    console.log(`相机调整完成：
    模型中心：${center.toArray().map(v => v.toFixed(2))}
    模型尺寸：${size.toArray().map(v => v.toFixed(2))}
    相机位置：${camera.position.toArray().map(v => v.toFixed(2))}
    视锥体：near=${camera.near.toFixed(2)}, far=${camera.far.toFixed(2)}`);
};

</script>

<style>
.three-container {
  width: 100%;
  /* height: calc(60vh - 6px);  */
  border: 1px solid #ccc; /* 可选：添加边框以便查看容器范围 */
}
.el-checkbox__label{
  font-size: 12px;
}
.color-card-canvas {
  pointer-events: none; /* 允许点击穿透 */
  border: 1px solid #ccc;
  background: white;
}
</style>