<template>
  <div class="cad-preview-page">
    <n-card title="三维模型预览（本地）" size="small">
      <n-alert type="info" :bordered="false" style="margin-bottom: 16px">
        上传 <strong>.glb</strong> 或 <strong>.gltf</strong> 即可在浏览器中预览。
        推荐使用单文件 <strong>.glb</strong>；gltf 若依赖外部 .bin / 贴图可能无法加载。
      </n-alert>

      <div class="upload-row">
        <n-upload
          :max="1"
          accept=".glb,.gltf"
          :show-file-list="true"
          :default-upload="false"
          @change="onFileChange"
        >
          <n-upload-dragger style="padding: 24px 32px">
            <div style="margin-bottom: 8px">
              <n-icon size="40" :depth="3"><CloudUploadOutline /></n-icon>
            </div>
            <n-text>点击或拖拽 glb / gltf 到此处</n-text>
          </n-upload-dragger>
        </n-upload>
        <n-space v-if="currentFile" vertical align="start">
          <n-text depth="3">当前文件</n-text>
          <n-tag type="info" :bordered="false">{{ currentFile.name }}</n-tag>
          <n-text depth="3">{{ formatSize(currentFile.size) }}</n-text>
          <n-button size="small" quaternary @click="clearFile">清除</n-button>
        </n-space>
      </div>

      <div class="viewer-wrap">
        <CadModelViewer v-if="currentFile" :file="currentFile" />
        <div v-else class="viewer-placeholder">
          <n-empty description="请先上传模型文件" />
        </div>
      </div>
    </n-card>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue'
import {
  NCard, NAlert, NUpload, NUploadDragger, NIcon, NText, NTag, NButton, NSpace, NEmpty,
  type UploadFileInfo,
} from 'naive-ui'
import { CloudUploadOutline } from '@vicons/ionicons5'
import CadModelViewer from '@/components/CadModelViewer.vue'

const currentFile = ref<File | null>(null)

function onFileChange({ fileList }: { fileList: UploadFileInfo[] }) {
  const item = fileList[fileList.length - 1]
  currentFile.value = item?.file ?? null
}

function clearFile() {
  currentFile.value = null
}

function formatSize(bytes: number) {
  if (bytes < 1024) return `${bytes} B`
  if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`
  return `${(bytes / 1024 / 1024).toFixed(2)} MB`
}
</script>

<style scoped>
.cad-preview-page {
  padding: 16px;
}

.upload-row {
  display: flex;
  gap: 24px;
  align-items: flex-start;
  margin-bottom: 16px;
  flex-wrap: wrap;
}

.upload-row :deep(.n-upload) {
  flex: 1;
  min-width: 280px;
  max-width: 480px;
}

.viewer-wrap {
  height: calc(100vh - 320px);
  min-height: 480px;
}

.viewer-placeholder {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
  min-height: 480px;
  border: 1px dashed var(--n-border-color);
  border-radius: 8px;
  background: var(--n-action-color);
}
</style>
