<template>
  <div class="result-visualization">
    <el-card class="visualization-card">
      <template #header>
        <div class="card-header">
          <h3>结果可视化</h3>
          <div class="visualization-controls">
            <el-select 
              v-model="visualizationType" 
              placeholder="选择可视化类型"
              @change="renderVisualization"
            >
              <el-option label="图表" value="chart" />
              <el-option label="图像对比" value="image-comparison" />
              <el-option label="表格" value="table" />
              <el-option label="3D可视化" value="3d" />
            </el-select>
            
            <el-button @click="exportResult">
              <el-icon><Download /></el-icon>
              导出结果
            </el-button>
          </div>
        </div>
      </template>
      
      <!-- 图表可视化 -->
      <div v-if="visualizationType === 'chart'" class="chart-container">
        <div ref="chartContainer" class="chart-wrapper"></div>
      </div>
      
      <!-- 图像对比 -->
      <div v-else-if="visualizationType === 'image-comparison'" class="image-comparison-container">
        <div class="comparison-grid">
          <div v-for="(item, index) in comparisonData" :key="index" class="comparison-item">
            <h4>{{ item.title }}</h4>
            <img :src="item.imageUrl" :alt="item.title" class="comparison-image" />
            <p class="comparison-label">{{ item.label }}</p>
          </div>
        </div>
      </div>
      
      <!-- 表格可视化 -->
      <div v-else-if="visualizationType === 'table'" class="table-container">
        <el-table :data="tableData" style="width: 100%" border>
          <el-table-column 
            v-for="column in tableColumns" 
            :key="column.prop" 
            :prop="column.prop" 
            :label="column.label"
            :formatter="column.formatter"
          />
        </el-table>
      </div>
      
      <!-- 3D可视化 -->
      <div v-else-if="visualizationType === '3d'" class="three-d-container">
        <div ref="threeContainer" class="three-wrapper"></div>
      </div>
      
      <!-- 通用可视化 -->
      <div v-else class="generic-container">
        <pre>{{ JSON.stringify(resultData, null, 2) }}</pre>
      </div>
    </el-card>
    
    <!-- 效果对比面板 -->
    <el-card v-if="enableComparison" class="comparison-panel">
      <template #header>
        <h3>效果对比</h3>
      </template>
      
      <div class="comparison-controls">
        <el-button @click="addComparisonItem">添加对比项</el-button>
        <el-button @click="compareResults">开始对比</el-button>
      </div>
      
      <div class="comparison-results">
        <div v-for="(item, index) in comparisonItems" :key="index" class="comparison-result-item">
          <div class="result-header">
            <span class="result-title">{{ item.title }}</span>
            <el-button size="small" type="danger" @click="removeComparisonItem(index)">删除</el-button>
          </div>
          <div class="result-content">
            <div v-if="item.type === 'image'">
              <img :src="item.data" :alt="item.title" class="result-image" />
            </div>
            <div v-else-if="item.type === 'data'">
              <pre>{{ JSON.stringify(item.data, null, 2) }}</pre>
            </div>
            <div v-else>
              <p>结果类型: {{ item.type }}</p>
            </div>
          </div>
        </div>
      </div>
    </el-card>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, onUnmounted, watch } from 'vue'
import { ElMessage } from 'element-plus'
import { Download } from '@element-plus/icons-vue'
import * as echarts from 'echarts'
import * as THREE from 'three'

// 定义props
interface Props {
  resultData?: any
  enableComparison?: boolean
  algorithmType?: string
}

const props = withDefaults(defineProps<Props>(), {
  resultData: () => ({}),
  enableComparison: false,
  algorithmType: 'general'
})

// 引用
const chartContainer = ref<HTMLDivElement>()
const threeContainer = ref<HTMLDivElement>()
const chartInstance = ref<echarts.ECharts | null>(null)
const threeScene = ref<THREE.Scene | null>(null)
const threeCamera = ref<THREE.PerspectiveCamera | null>(null)
const threeRenderer = ref<THREE.WebGLRenderer | null>(null)

// 状态
const visualizationType = ref('chart')
const comparisonItems = ref<any[]>([])
const comparisonData = ref<any[]>([])
const tableData = ref<any[]>([])
const tableColumns = ref<any[]>([])

// 初始化
onMounted(() => {
  // 根据结果数据类型自动选择可视化类型
  if (props.resultData) {
    detectVisualizationType(props.resultData)
  }
  
  // 初始化图表
  initChart()
  init3D()
})

onUnmounted(() => {
  // 销毁图表实例
  if (chartInstance.value) {
    chartInstance.value.dispose()
  }
  
  // 销毁3D场景
  destroy3D()
})

// 监听结果数据变化
watch(() => props.resultData, (newData) => {
  if (newData) {
    detectVisualizationType(newData)
    renderVisualization()
  }
})

// 方法
const detectVisualizationType = (data: any) => {
  if (data && typeof data === 'object') {
    if (data.images || data.image_urls) {
      visualizationType.value = 'image-comparison'
    } else if (Array.isArray(data) && data.length > 0) {
      visualizationType.value = 'table'
    } else if (data.chart_data) {
      visualizationType.value = 'chart'
    } else {
      visualizationType.value = 'chart' // 默认图表
    }
  }
}

const initChart = () => {
  if (chartContainer.value) {
    chartInstance.value = echarts.init(chartContainer.value)
    window.addEventListener('resize', handleResize)
  }
}

const handleResize = () => {
  if (chartInstance.value) {
    chartInstance.value.resize()
  }
}

const renderVisualization = () => {
  switch (visualizationType.value) {
    case 'chart':
      renderChart()
      break
    case 'image-comparison':
      renderImageComparison()
      break
    case 'table':
      renderTable()
      break
    case '3d':
      render3D()
      break
    default:
      // 通用显示
      break
  }
}

const renderChart = () => {
  if (!chartInstance.value) return
  
  // 根据数据类型生成不同的图表配置
  const option = getChartOption(props.resultData)
  chartInstance.value.setOption(option)
}

const getChartOption = (data: any) => {
  // 简化的图表配置，实际应用中需要根据数据类型动态生成
  if (Array.isArray(data) && data.length > 0) {
    // 假设是柱状图数据
    return {
      title: {
        text: '结果可视化'
      },
      tooltip: {},
      xAxis: {
        type: 'category',
        data: data.map((item: any, index: number) => `项目${index + 1}`)
      },
      yAxis: {
        type: 'value'
      },
      series: [{
        data: data.map((item: any) => typeof item === 'object' ? item.value || 0 : item),
        type: 'bar'
      }]
    }
  } else if (typeof data === 'object' && data.labels && data.datasets) {
    // 假设是饼图数据
    return {
      title: {
        text: '结果可视化'
      },
      tooltip: {
        trigger: 'item'
      },
      legend: {
        orient: 'vertical',
        left: 'left'
      },
      series: [{
        name: '结果',
        type: 'pie',
        radius: '50%',
        data: data.datasets,
        emphasis: {
          itemStyle: {
            shadowBlur: 10,
            shadowOffsetX: 0,
            shadowColor: 'rgba(0, 0, 0, 0.5)'
          }
        }
      }]
    }
  } else {
    // 默认柱状图
    return {
      title: {
        text: '结果可视化'
      },
      tooltip: {},
      xAxis: {
        type: 'category',
        data: ['结果']
      },
      yAxis: {
        type: 'value'
      },
      series: [{
        data: [JSON.stringify(data).length],
        type: 'bar'
      }]
    }
  }
}

const renderImageComparison = () => {
  // 处理图像对比数据
  if (props.resultData && props.resultData.images) {
    comparisonData.value = props.resultData.images.map((img: any, index: number) => ({
      title: `结果 ${index + 1}`,
      imageUrl: img.url || img,
      label: img.label || `图像 ${index + 1}`
    }))
  } else {
    comparisonData.value = []
  }
}

const renderTable = () => {
  // 处理表格数据
  if (Array.isArray(props.resultData)) {
    tableData.value = props.resultData
    // 生成列定义
    if (props.resultData.length > 0) {
      tableColumns.value = Object.keys(props.resultData[0]).map(key => ({
        prop: key,
        label: key,
        formatter: (row: any, column: any, cellValue: any) => {
          if (typeof cellValue === 'object') {
            return JSON.stringify(cellValue)
          }
          return cellValue
        }
      }))
    }
  } else if (typeof props.resultData === 'object') {
    // 如果是对象，转换为单行表格
    tableData.value = [props.resultData]
    tableColumns.value = Object.keys(props.resultData).map(key => ({
      prop: key,
      label: key
    }))
  }
}

const init3D = () => {
  if (threeContainer.value) {
    // 初始化Three.js场景
    threeScene.value = new THREE.Scene()
    threeCamera.value = new THREE.PerspectiveCamera(75, threeContainer.value.clientWidth / threeContainer.value.clientHeight, 0.1, 1000)
    threeRenderer.value = new THREE.WebGLRenderer({ antialias: true })
    
    threeRenderer.value.setSize(threeContainer.value.clientWidth, threeContainer.value.clientHeight)
    threeContainer.value.appendChild(threeRenderer.value.domElement)
    
    // 添加基本几何体
    const geometry = new THREE.BoxGeometry()
    const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 })
    const cube = new THREE.Mesh(geometry, material)
    threeScene.value.add(cube)
    
    threeCamera.value.position.z = 5
    
    // 开始动画循环
    animate3D()
  }
}

const animate3D = () => {
  if (threeScene.value && threeCamera.value && threeRenderer.value && threeContainer.value) {
    requestAnimationFrame(animate3D)
    
    // 旋转立方体
    const objects = threeScene.value.children.filter(obj => obj instanceof THREE.Mesh)
    objects.forEach(obj => {
      obj.rotation.x += 0.01
      obj.rotation.y += 0.01
    })
    
    threeRenderer.value.setSize(threeContainer.value.clientWidth, threeContainer.value.clientHeight)
    threeRenderer.value.render(threeScene.value, threeCamera.value)
  }
}

const render3D = () => {
  // 3D渲染由动画循环处理
}

const destroy3D = () => {
  if (threeRenderer.value && threeContainer.value) {
    threeContainer.value.removeChild(threeRenderer.value.domElement)
  }
  if (threeRenderer.value) {
    threeRenderer.value.dispose()
  }
}

const exportResult = () => {
  // 导出结果的实现
  const dataStr = JSON.stringify(props.resultData, null, 2)
  const dataUri = 'data:application/json;charset=utf-8,'+ encodeURIComponent(dataStr)
  
  const exportFileDefaultName = 'result_export.json'
  
  const linkElement = document.createElement('a')
  linkElement.setAttribute('href', dataUri)
  linkElement.setAttribute('download', exportFileDefaultName)
  linkElement.click()
  
  ElMessage.success('结果已导出')
}

const addComparisonItem = () => {
  // 添加对比项
  comparisonItems.value.push({
    title: `对比项 ${comparisonItems.value.length + 1}`,
    type: 'data',
    data: props.resultData
  })
}

const removeComparisonItem = (index: number) => {
  comparisonItems.value.splice(index, 1)
}

const compareResults = () => {
  // 执行对比分析
  if (comparisonItems.value.length < 2) {
    ElMessage.warning('至少需要两个对比项')
    return
  }
  
  ElMessage.success(`已对 ${comparisonItems.value.length} 个结果进行对比`)
  // 这里可以添加具体的对比逻辑
}
</script>

<style scoped>
.result-visualization {
  width: 100%;
}

.visualization-card {
  margin-bottom: 20px;
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.visualization-controls {
  display: flex;
  gap: 10px;
}

.chart-container {
  width: 100%;
  height: 400px;
}

.chart-wrapper {
  width: 100%;
  height: 100%;
}

.image-comparison-container {
  padding: 20px 0;
}

.comparison-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
  gap: 20px;
}

.comparison-item {
  text-align: center;
}

.comparison-image {
  max-width: 100%;
  height: 200px;
  object-fit: contain;
  border: 1px solid #ebeef5;
  border-radius: 4px;
}

.comparison-label {
  margin-top: 10px;
  font-size: 14px;
  color: #909399;
}

.table-container {
  padding: 20px 0;
}

.three-d-container {
  width: 100%;
  height: 400px;
}

.three-wrapper {
  width: 100%;
  height: 100%;
}

.generic-container {
  padding: 20px;
  background-color: #f5f5f5;
  border-radius: 4px;
  overflow-x: auto;
}

.comparison-panel {
  margin-top: 20px;
}

.comparison-controls {
  margin-bottom: 20px;
  display: flex;
  gap: 10px;
}

.comparison-results {
  display: flex;
  flex-direction: column;
  gap: 15px;
}

.comparison-result-item {
  border: 1px solid #ebeef5;
  border-radius: 4px;
  padding: 15px;
}

.result-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 10px;
  padding-bottom: 10px;
  border-bottom: 1px solid #ebeef5;
}

.result-title {
  font-weight: bold;
  color: #333;
}

.result-image {
  max-width: 100%;
  height: 150px;
  object-fit: contain;
  border: 1px solid #eee;
  border-radius: 4px;
}

.result-content {
  padding: 10px 0;
}
</style>
</template>
</file_path>