<script>
export default {
  name: 'ModelGalleryPage'
}
</script>

<template>
  <div class="model-gallery-page">
    <!-- 工具栏 -->
    <div class="toolbar">
      <button class="toolbar-btn toolbar-btn-primary" @click="openModel">
        <i class="fas fa-folder-open"></i>
        <span>打开模型</span>
      </button>
    </div>

    <!-- 主内容区域 -->
    <div class="main-content">
      <!-- 模型树侧边栏 -->
      <div v-if="hasModel && modelTree" class="model-tree-sidebar">
        <div class="sidebar-header">
          <i class="fas fa-sitemap"></i>
          <span>模型结构树</span>
        </div>
        <div class="tree-container">
          <ModelTreeNode :node="modelTree" />
        </div>
      </div>

      <!-- 3D查看器容器 -->
      <div
        class="viewer-wrapper"
        :class="{ dragging: isDragging }"
        @dragover="handleDragOver"
        @dragleave="handleDragLeave"
        @drop="handleDrop"
      >
        <div v-if="!hasModel" class="empty-state">
          <div class="empty-icon">
            <i class="fas fa-cube"></i>
          </div>
          <h3>未加载模型</h3>
          <p>点击"打开模型"按钮选择3D模型文件</p>
          <p>或将模型文件拖拽到此处</p>
          <p class="supported-formats">支持格式: OBJ, STL, GLTF, GLB, PLY, 3DS, FBX</p>
        </div>
        <div ref="viewerContainer" class="viewer-container" :class="{ hidden: !hasModel }"></div>
        <div v-if="isLoading" class="loading-overlay">
          <div class="loading-spinner"></div>
          <p>加载模型中...</p>
        </div>
      </div>
    </div>

    <!-- 模型信息面板 -->
    <div v-if="modelInfo" class="model-info-panel">
      <div class="info-item">
        <i class="fas fa-file"></i>
        <span class="info-label">文件名:</span>
        <span class="info-value">{{ modelInfo.fileName }}</span>
      </div>
      <div class="info-divider"></div>
      <div class="info-item">
        <i class="fas fa-cube"></i>
        <span class="info-label">顶点数:</span>
        <span class="info-value">{{ modelInfo.vertices?.toLocaleString() || '-' }}</span>
      </div>
      <div class="info-divider"></div>
      <div class="info-item">
        <i class="fas fa-shapes"></i>
        <span class="info-label">面数:</span>
        <span class="info-value">{{ modelInfo.faces?.toLocaleString() || '-' }}</span>
      </div>
      <div class="info-divider"></div>
      <div class="info-item">
        <i class="fas fa-layer-group"></i>
        <span class="info-label">网格数:</span>
        <span class="info-value">{{ modelInfo.meshes || '-' }}</span>
      </div>
    </div>
  </div>
</template>

<script setup>
import * as OV from 'online-3d-viewer'
import { ref, onMounted, onBeforeUnmount } from 'vue'
import ModelTreeNode from '@/components/ui/ModelTreeNode.vue'

// 查看器引用
const viewerContainer = ref(null)
let viewer = null

// 状态管理
const hasModel = ref(false)
const isLoading = ref(false)
const modelInfo = ref(null)
const modelTree = ref(null) // 模型树数据
const isDragging = ref(false) // 拖拽状态

// 初始化查看器
onMounted(() => {
  if (viewerContainer.value) {
    viewer = new OV.EmbeddedViewer(viewerContainer.value, {
      backgroundColor: new OV.RGBAColor(220, 222, 225, 255),
      defaultColor: new OV.RGBColor(150, 150, 150),
      edgeSettings: new OV.EdgeSettings(false, new OV.RGBColor(80, 80, 80), 1),
      onModelLoaded: handleModelLoaded
    })
  }
})

// 清理资源
onBeforeUnmount(() => {
  if (viewer) {
    viewer.Destroy()
    viewer = null
  }
})

// 打开模型文件
const openModel = () => {
  const input = document.createElement('input')
  input.type = 'file'
  input.accept = '.obj,.stl,.gltf,.glb,.ply,.3ds,.fbx,.ifc,.off,.3dm'
  input.multiple = true
  input.onchange = async (e) => {
    const files = Array.from(e.target.files)
    if (files.length > 0) {
      await loadModelFiles(files)
    }
  }
  input.click()
}

// 加载模型文件（复用逻辑）
const loadModelFiles = async (files) => {
  isLoading.value = true
  hasModel.value = false
  modelInfo.value = null

  try {
    await viewer.LoadModelFromFileList(files)
    hasModel.value = true
    modelInfo.value = {
      fileName: files[0].name
    }
  } catch {
    hasModel.value = false
    isLoading.value = false
  }
}

// 支持的文件扩展名
const supportedExtensions = ['.obj', '.stl', '.gltf', '.glb', '.ply', '.3ds', '.fbx', '.ifc', '.off', '.3dm']

// 拖拽进入
const handleDragOver = (e) => {
  e.preventDefault()
  e.stopPropagation()
  isDragging.value = true
}

// 拖拽离开
const handleDragLeave = (e) => {
  e.preventDefault()
  e.stopPropagation()
  // 只有离开整个容器才取消高亮
  if (e.target === e.currentTarget) {
    isDragging.value = false
  }
}

// 拖拽释放
const handleDrop = async (e) => {
  e.preventDefault()
  e.stopPropagation()
  isDragging.value = false

  const files = Array.from(e.dataTransfer.files)
  if (files.length === 0) return

  // 验证文件格式
  const validFiles = files.filter((file) => {
    const ext = '.' + file.name.split('.').pop().toLowerCase()
    return supportedExtensions.includes(ext)
  })

  if (validFiles.length > 0) {
    await loadModelFiles(validFiles)
  }
}

// 构建模型树结构
const buildModelTree = (model) => {
  if (!model) return null

  // 递归构建节点树
  const buildNodeTree = (node, depth = 0) => {
    const nodeName = node.GetName() || (node.HasParent() ? '未命名节点' : '根节点')
    const nodeData = {
      name: nodeName,
      type: 'node',
      depth: depth,
      children: [],
      expanded: depth < 2 // 默认展开前两层
    }

    // 添加子节点
    for (const childNode of node.GetChildNodes()) {
      nodeData.children.push(buildNodeTree(childNode, depth + 1))
    }

    // 添加网格
    for (const meshIndex of node.GetMeshIndices()) {
      const mesh = model.GetMesh(meshIndex)
      const meshName = mesh.GetName() || `网格 ${meshIndex}`
      nodeData.children.push({
        name: meshName,
        type: 'mesh',
        depth: depth + 1,
        meshIndex: meshIndex,
        vertexCount: mesh.VertexCount(),
        triangleCount: mesh.TriangleCount()
      })
    }

    return nodeData
  }

  const rootNode = model.GetRootNode()
  return buildNodeTree(rootNode)
}

// 模型加载完成回调
const handleModelLoaded = () => {
  isLoading.value = false

  // 强制调整canvas尺寸，确保模型正确显示
  setTimeout(() => {
    if (viewer) {
      viewer.Resize()
    }
  }, 100)

  // 获取模型统计信息
  try {
    const model = viewer.GetModel()
    if (model) {
      let totalVertices = 0
      let totalFaces = 0
      let meshCount = 0

      // 遍历模型获取统计信息
      model.EnumerateMeshes((mesh) => {
        totalVertices += mesh.VertexCount()
        totalFaces += mesh.TriangleCount()
        meshCount++
      })

      if (modelInfo.value) {
        modelInfo.value.vertices = totalVertices
        modelInfo.value.faces = totalFaces
        modelInfo.value.meshes = meshCount
      }

      // 构建模型树
      modelTree.value = buildModelTree(model)
    }
  } catch (error) {
    console.error('获取模型统计信息失败:', error)
  }
}
</script>

<style scoped>
.model-gallery-page {
  height: 100%;
  display: flex;
  flex-direction: column;
  background: var(--color-bg-primary);
}

/* 主内容区域样式 */
.main-content {
  flex: 1;
  display: flex;
  overflow: hidden;
}

/* 工具栏样式 */
.toolbar {
  display: flex;
  align-items: center;
  gap: var(--spacing-sm);
  padding: var(--spacing-lg);
  background: var(--color-bg-secondary);
  border-bottom: 1px solid var(--color-border-primary);
  flex-shrink: 0;
}

.toolbar-btn {
  display: flex;
  align-items: center;
  gap: var(--spacing-sm);
  padding: var(--spacing-sm) var(--spacing-lg);
  background: var(--color-bg-tertiary);
  border: 1px solid var(--color-border-primary);
  border-radius: var(--size-border-radius-button);
  color: var(--color-text-primary);
  font-size: var(--font-size-base);
  cursor: pointer;
  transition: var(--transition-all);
}

.toolbar-btn:hover:not(:disabled) {
  background: var(--color-bg-hover);
  border-color: var(--color-primary);
  transform: translateY(-1px);
}

.toolbar-btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.toolbar-btn-primary {
  background: var(--color-primary-gradient);
  border-color: transparent;
  color: white;
}

.toolbar-btn-primary:hover:not(:disabled) {
  background: var(--color-primary-gradient-hover);
  box-shadow: 0 4px 15px var(--color-primary-rgb-3);
}

.toolbar-btn i {
  font-size: var(--font-size-lg);
}

.toolbar-divider {
  width: 1px;
  height: var(--spacing-3xl);
  background: var(--color-border-primary);
  margin: 0 var(--spacing-sm);
}

/* 模型树侧边栏样式 */
.model-tree-sidebar {
  width: 300px;
  background: var(--color-bg-secondary);
  border-right: 1px solid var(--color-border-primary);
  display: flex;
  flex-direction: column;
  flex-shrink: 0;
}

.sidebar-header {
  display: flex;
  align-items: center;
  gap: var(--spacing-sm);
  padding: var(--spacing-lg);
  background: var(--color-bg-tertiary);
  border-bottom: 1px solid var(--color-border-primary);
  color: var(--color-text-primary);
  font-weight: var(--font-weight-semibold);
  font-size: var(--font-size-base);
}

.sidebar-header i {
  color: var(--color-primary);
}

.tree-container {
  flex: 1;
  overflow-y: auto;
  padding: var(--spacing-sm);
}

/* 查看器容器样式 */
.viewer-wrapper {
  flex: 1;
  position: relative;
  overflow: hidden;
  background: var(--color-bg-viewer-light);
  transition: var(--transition-all);
}

/* 拖拽高亮样式 */
.viewer-wrapper.dragging {
  background: rgba(59, 130, 246, 0.05);
  border: 3px dashed var(--color-primary);
  box-shadow: inset 0 0 20px rgba(59, 130, 246, 0.2);
}

.viewer-wrapper.dragging .empty-state {
  opacity: 0.7;
  transform: scale(0.95);
  transition: var(--transition-all);
}

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

.viewer-container.hidden {
  display: none;
}

/* 空状态样式 */
.empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 100%;
  text-align: center;
  padding: var(--spacing-3xl);
}

.empty-icon {
  width: var(--size-96);
  height: var(--size-96);
  background: var(--color-primary-gradient);
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: var(--spacing-2xl);
  box-shadow: 0 8px 32px var(--color-primary-rgb-3);
}

.empty-icon i {
  font-size: var(--font-size-6xl);
  color: white;
}

.empty-state h3 {
  color: var(--color-text-primary);
  font-size: var(--font-size-2xl);
  font-weight: var(--font-weight-semibold);
  margin: 0 0 var(--spacing-md) 0;
}

.empty-state p {
  color: var(--color-text-primary);
  font-size: var(--font-size-lg);
  margin: 0 0 var(--spacing-sm) 0;
  line-height: 1.6;
}

.supported-formats {
  color: var(--color-text-tertiary);
  font-size: var(--font-size-sm);
  margin-top: var(--spacing-lg);
  padding: var(--spacing-md) var(--spacing-xl);
  background: var(--color-bg-secondary);
  border-radius: var(--size-border-radius);
  border: 1px solid var(--color-border-primary);
}

/* 加载状态样式 */
.loading-overlay {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(30, 35, 45, 0.9);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  z-index: 100;
}

.loading-spinner {
  width: var(--size-64);
  height: var(--size-64);
  border: 4px solid var(--color-border-primary);
  border-top-color: var(--color-primary);
  border-radius: 50%;
  animation: spin 1s linear infinite;
}

@keyframes spin {
  to {
    transform: rotate(360deg);
  }
}

.loading-overlay p {
  color: var(--color-text-primary);
  font-size: var(--font-size-lg);
  margin-top: var(--spacing-xl);
}

/* 模型信息面板样式 */
.model-info-panel {
  display: flex;
  align-items: center;
  gap: var(--spacing-md);
  padding: var(--spacing-lg) var(--spacing-xl);
  background: var(--color-bg-secondary);
  border-top: 1px solid var(--color-border-primary);
  flex-shrink: 0;
}

.info-item {
  display: flex;
  align-items: center;
  gap: var(--spacing-sm);
}

.info-item i {
  color: var(--color-primary);
  font-size: var(--font-size-base);
}

.info-label {
  color: var(--color-text-secondary);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-medium);
}

.info-value {
  color: var(--color-text-primary);
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-semibold);
}

.info-divider {
  width: 1px;
  height: var(--spacing-2xl);
  background: var(--color-border-primary);
  margin: 0 var(--spacing-sm);
}

/* 响应式设计 */
@media (max-width: 768px) {
  .main-content {
    flex-direction: column;
  }

  .model-tree-sidebar {
    width: 100%;
    max-height: 200px;
    border-right: none;
    border-bottom: 1px solid var(--color-border-primary);
  }

  .toolbar {
    padding: var(--spacing-md);
    gap: var(--spacing-xs);
    flex-wrap: wrap;
  }

  .toolbar-btn span {
    display: none;
  }

  .toolbar-btn {
    padding: var(--spacing-sm);
  }

  .model-info-panel {
    flex-wrap: wrap;
    padding: var(--spacing-md);
  }

  .info-item {
    flex: 1 1 45%;
  }

  .empty-icon {
    width: var(--size-64);
    height: var(--size-64);
  }

  .empty-icon i {
    font-size: var(--font-size-4xl);
  }

  .empty-state h3 {
    font-size: var(--font-size-xl);
  }

  .empty-state p {
    font-size: var(--font-size-base);
  }
}
</style>
