<template>
  <a-drawer
    v-model:open="visible"
    title="参赛作品"
    placement="right"
    width="600px"
    :footer-style="{ textAlign: 'right', padding: '16px 24px' }"
    @close="handleCancel"
  >
    <template #title>
      <div class="drawer-title">
        <span>参赛作品</span>
      </div>
    </template>

    <a-spin :spinning="loading">
      <div v-if="!work" class="empty-container">
        <a-empty description="暂无作品" />
      </div>

      <div v-else class="work-detail">
        <!-- 多模型预览网格 -->
        <div class="models-preview-grid">
          <div
            v-for="(model, index) in modelItems"
            :key="index"
            class="model-preview-card"
            @mouseenter="hoveredIndex = index"
            @mouseleave="hoveredIndex = -1"
          >
            <!-- 预览图 -->
            <img
              v-if="model.previewUrl"
              :src="model.previewUrl"
              alt="模型预览"
              class="preview-image"
              @error="(e) => handlePreviewError(e, index)"
            />
            <div v-else class="preview-placeholder">
              <FileImageOutlined class="placeholder-icon" />
              <span>模型 {{ index + 1 }}</span>
            </div>

            <!-- 悬浮操作按钮 -->
            <transition name="fade">
              <div v-show="hoveredIndex === index" class="actions-overlay">
                <a-button
                  v-if="model.fileUrl && is3DModelFile(model.fileUrl)"
                  type="primary"
                  size="small"
                  @click="handlePreview3DModel(model.fileUrl, index)"
                >
                  <template #icon><EyeOutlined /></template>
                  3D预览
                </a-button>
              </div>
            </transition>

            <!-- 模型序号 -->
            <div class="model-index">{{ index + 1 }}</div>
          </div>
        </div>

        <!-- 下载按钮 -->
        <div v-if="modelItems.length > 0" class="download-section">
          <a-button @click="handleDownloadWork">
            <template #icon><DownloadOutlined /></template>
            下载全部模型
          </a-button>
        </div>

        <!-- 作品信息 -->
        <div class="work-info-section">
          <div class="info-row">
            <span class="info-label">作品名称</span>
            <span class="info-value">{{ work.title }}</span>
          </div>
          <div class="info-row">
            <span class="info-label">作品介绍</span>
            <span class="info-value description">{{ work.description || "暂无介绍" }}</span>
          </div>
          <div class="info-row">
            <span class="info-label">作品编号</span>
            <span class="info-value">{{ work.workNo || "-" }}</span>
          </div>
          <div class="info-row">
            <span class="info-label">提交时间</span>
            <span class="info-value">{{ formatDateTime(work.submitTime) }}</span>
          </div>
          <div class="info-row">
            <span class="info-label">作品状态</span>
            <a-tag :color="getStatusColor(work.status)">
              {{ getStatusText(work.status) }}
            </a-tag>
          </div>
          <div v-if="work.version" class="info-row">
            <span class="info-label">版本号</span>
            <span class="info-value">v{{ work.version }}</span>
          </div>
        </div>

        <!-- 上传的附件 -->
        <div
          v-if="work.attachments && work.attachments.length > 0"
          class="attachments-section"
        >
          <div class="section-title">上传附件</div>
          <div class="attachments-list">
            <div
              v-for="attachment in work.attachments"
              :key="attachment.id"
              class="attachment-item"
            >
              <div class="attachment-info">
                <FileOutlined class="attachment-icon" />
                <span class="attachment-name">{{ attachment.fileName }}</span>
                <span v-if="attachment.size" class="attachment-size">
                  ({{ formatFileSize(attachment.size) }})
                </span>
              </div>
              <a-button
                type="link"
                size="small"
                @click="handleDownloadAttachment(attachment)"
              >
                <template #icon><DownloadOutlined /></template>
                下载
              </a-button>
            </div>
          </div>
        </div>
      </div>
    </a-spin>

    <template #footer>
      <a-button @click="handleCancel">关闭</a-button>
    </template>
  </a-drawer>
</template>

<script setup lang="ts">
import { ref, watch, computed } from "vue"
import { useRouter, useRoute } from "vue-router"
import { message } from "ant-design-vue"
import {
  FileOutlined,
  FileImageOutlined,
  DownloadOutlined,
  EyeOutlined,
} from "@ant-design/icons-vue"
import { worksApi, registrationsApi, type ContestWork } from "@/api/contests"
import { useAuthStore } from "@/stores/auth"
import dayjs from "dayjs"

interface Props {
  open: boolean
  contestId: number
}

interface Emits {
  (e: "update:open", value: boolean): void
}

const props = defineProps<Props>()
const emit = defineEmits<Emits>()

const router = useRouter()
const route = useRoute()
const authStore = useAuthStore()
const visible = ref(false)
const loading = ref(false)
const work = ref<ContestWork | null>(null)
const hoveredIndex = ref(-1)
const previewErrors = ref<Record<number, boolean>>({})

// 监听抽屉打开状态
watch(
  () => props.open,
  async (newVal) => {
    visible.value = newVal
    if (newVal) {
      previewErrors.value = {}
      await fetchUserWork()
    } else {
      work.value = null
      hoveredIndex.value = -1
    }
  },
  { immediate: true }
)

watch(visible, (newVal) => {
  emit("update:open", newVal)
})

// 获取当前用户的作品
const fetchUserWork = async () => {
  loading.value = true
  work.value = null
  try {
    const userId = authStore.user?.id
    if (!userId) {
      message.error("用户未登录，无法查看作品")
      visible.value = false
      return
    }

    // 获取用户的报名记录（包括作为团队成员的情况）
    const registration = await registrationsApi.getMyRegistration(props.contestId)

    if (!registration) {
      message.warning("您尚未报名该活动或报名未通过，无法查看作品")
      visible.value = false
      return
    }

    const registrationId = registration.id

    // 获取该报名的所有作品版本，取最新版本
    const works = await worksApi.getVersions(registrationId)
    if (works && works.length > 0) {
      // 找到最新版本的作品
      const latestWork = works.find((w) => w.isLatest) || works[0]
      work.value = latestWork
    } else {
      message.warning("您尚未提交作品")
    }
  } catch (error: any) {
    message.error(error?.response?.data?.message || "获取作品信息失败")
  } finally {
    loading.value = false
  }
}

// 模型项目列表 - 解析 files 和 previewUrls 数组
interface ModelItem {
  fileUrl: string
  previewUrl: string
}

const modelItems = computed<ModelItem[]>(() => {
  if (!work.value) return []

  // 解析 files 数组
  let files = work.value.files || []
  if (typeof files === "string") {
    try {
      files = JSON.parse(files)
    } catch {
      files = []
    }
  }
  if (!Array.isArray(files)) files = []

  // 解析 previewUrls 数组
  let previewUrls = work.value.previewUrls || []
  if (typeof previewUrls === "string") {
    try {
      previewUrls = JSON.parse(previewUrls)
    } catch {
      previewUrls = []
    }
  }
  if (!Array.isArray(previewUrls)) previewUrls = []

  // 如果没有 previewUrls 但有单个 previewUrl，使用它
  if (previewUrls.length === 0 && work.value.previewUrl) {
    previewUrls = [work.value.previewUrl]
  }

  // 过滤出3D模型文件（排除附件等）
  const modelFiles = files.filter((f: any) => {
    const url = typeof f === "object" && f?.fileUrl ? f.fileUrl : f
    return url && is3DModelFile(url)
  })

  // 构建模型项目列表
  return modelFiles.map((f: any, index: number) => {
    const fileUrl = typeof f === "object" && f?.fileUrl ? f.fileUrl : f
    const previewUrl = previewUrls[index] || previewUrls[0] || ""
    return {
      fileUrl: getFileUrl(fileUrl),
      previewUrl: previewUrl && !previewErrors.value[index] ? getFileUrl(previewUrl) : "",
    }
  })
})

// 作品文件列表（用于下载）
const workFiles = computed(() => {
  if (!work.value) return []
  let files = work.value.files || []

  if (typeof files === "string") {
    try {
      files = JSON.parse(files)
    } catch {
      return []
    }
  }

  if (!Array.isArray(files)) return []

  return files.map((f: any) => {
    return typeof f === "object" && f?.fileUrl ? f.fileUrl : f
  }).filter(Boolean)
})

// 判断是否为3D模型文件
const is3DModelFile = (fileUrl: string): boolean => {
  const modelExtensions = [
    ".glb",
    ".gltf",
    ".obj",
    ".fbx",
    ".3ds",
    ".dae",
    ".stl",
    ".ply",
    ".zip",
  ]
  const lowerUrl = fileUrl.toLowerCase()
  return modelExtensions.some((ext) => lowerUrl.includes(ext))
}

// 获取文件URL（处理相对路径）
const getFileUrl = (fileUrl: string): string => {
  if (!fileUrl) return ""
  // 如果已经是完整URL，直接返回
  if (fileUrl.startsWith("http://") || fileUrl.startsWith("https://")) {
    return fileUrl
  }
  // 如果是相对路径，拼接API基础URL
  const baseURL = import.meta.env.VITE_API_BASE_URL || ""
  if (fileUrl.startsWith("/api") && baseURL.includes("/api")) {
    const urlWithoutApi = baseURL.replace(/\/api$/, "")
    return `${urlWithoutApi}${fileUrl}`
  }
  return `${baseURL}${fileUrl.startsWith("/") ? "" : "/"}${fileUrl}`
}

// 预览图加载错误
const handlePreviewError = (_e: Event, index: number) => {
  previewErrors.value[index] = true
}

// 预览3D模型 - 支持多模型预览
const handlePreview3DModel = (fileUrl: string, index: number) => {
  if (!fileUrl) {
    message.error("文件路径无效")
    return
  }

  const tenantCode = route.params.tenantCode as string

  // 收集所有模型URL用于多模型切换
  const allModelUrls = modelItems.value.map((m) => m.fileUrl)

  // 存储到 sessionStorage（避免URL过长）
  if (allModelUrls.length > 1) {
    sessionStorage.setItem("model-viewer-urls", JSON.stringify(allModelUrls))
    sessionStorage.setItem("model-viewer-index", String(index))
    // 清除单URL存储
    sessionStorage.removeItem("model-viewer-url")
  } else {
    sessionStorage.setItem("model-viewer-url", fileUrl)
    sessionStorage.removeItem("model-viewer-urls")
    sessionStorage.removeItem("model-viewer-index")
  }

  // 不在URL上携带参数
  router.push({
    path: `/${tenantCode}/workbench/model-viewer`,
  })
}

// 下载作品 - 下载所有模型文件
const handleDownloadWork = () => {
  if (workFiles.value.length === 0) {
    message.error("无作品文件")
    return
  }

  // 下载所有3D模型文件
  workFiles.value.forEach((file, index) => {
    if (is3DModelFile(file)) {
      setTimeout(() => {
        const fileUrl = getFileUrl(file)
        const link = document.createElement("a")
        link.href = fileUrl
        link.download = `${work.value?.title || "作品"}_${index + 1}`
        link.target = "_blank"
        document.body.appendChild(link)
        link.click()
        document.body.removeChild(link)
      }, index * 500) // 错开下载时间
    }
  })
  message.success("开始下载作品")
}

// 下载附件
const handleDownloadAttachment = async (attachment: any) => {
  try {
    const fileUrl = getFileUrl(attachment.fileUrl)
    const link = document.createElement("a")
    link.href = fileUrl
    link.download = attachment.fileName
    link.target = "_blank"
    document.body.appendChild(link)
    link.click()
    document.body.removeChild(link)
    message.success("开始下载附件")
  } catch {
    message.error("下载附件失败")
  }
}

// 格式化日期时间
const formatDateTime = (dateStr?: string) => {
  if (!dateStr) return "-"
  return dayjs(dateStr).format("YYYY-MM-DD HH:mm:ss")
}

// 格式化文件大小
const formatFileSize = (size: string | number): string => {
  if (!size) return "-"
  const numSize = typeof size === "string" ? parseFloat(size) : size
  if (numSize < 1024) {
    return `${numSize} B`
  } else if (numSize < 1024 * 1024) {
    return `${(numSize / 1024).toFixed(2)} KB`
  } else if (numSize < 1024 * 1024 * 1024) {
    return `${(numSize / (1024 * 1024)).toFixed(2)} MB`
  } else {
    return `${(numSize / (1024 * 1024 * 1024)).toFixed(2)} GB`
  }
}

// 获取状态颜色
const getStatusColor = (
  status?: "submitted" | "locked" | "reviewing" | "rejected" | "accepted"
): string => {
  const colorMap: Record<string, string> = {
    submitted: "blue",
    locked: "default",
    reviewing: "processing",
    rejected: "error",
    accepted: "success",
  }
  return colorMap[status || "submitted"] || "default"
}

// 获取状态文本
const getStatusText = (
  status?: "submitted" | "locked" | "reviewing" | "rejected" | "accepted"
): string => {
  const textMap: Record<string, string> = {
    submitted: "已提交",
    locked: "已锁定",
    reviewing: "评审中",
    rejected: "已拒绝",
    accepted: "已通过",
  }
  return textMap[status || "submitted"] || "未知"
}

// 取消
const handleCancel = () => {
  visible.value = false
}
</script>

<style scoped lang="scss">
.drawer-title {
  font-size: 16px;
  font-weight: 500;
}

.empty-container {
  padding: 40px 0;
  text-align: center;
}

.work-detail {
  padding: 0;
}

// 多模型预览网格
.models-preview-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 12px;
  margin-bottom: 16px;
}

.model-preview-card {
  position: relative;
  aspect-ratio: 1;
  border-radius: 12px;
  overflow: hidden;
  background: #f5f5f5;
  cursor: pointer;
  transition: all 0.3s ease;
  border: 2px solid transparent;

  &:hover {
    border-color: #1890ff;
    box-shadow: 0 4px 12px rgba(24, 144, 255, 0.2);
  }

  .preview-image {
    width: 100%;
    height: 100%;
    object-fit: cover;
  }

  .preview-placeholder {
    width: 100%;
    height: 100%;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    color: rgba(0, 0, 0, 0.25);
    background: linear-gradient(135deg, #f5f5f5 0%, #e8e8e8 100%);

    .placeholder-icon {
      font-size: 36px;
      margin-bottom: 8px;
    }

    span {
      font-size: 12px;
    }
  }

  .model-index {
    position: absolute;
    top: 8px;
    left: 8px;
    width: 24px;
    height: 24px;
    background: rgba(0, 0, 0, 0.6);
    color: #fff;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 12px;
    font-weight: 500;
  }
}

// 悬浮操作层
.actions-overlay {
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.5);
  display: flex;
  align-items: center;
  justify-content: center;
}

// 下载区域
.download-section {
  margin-bottom: 20px;
  display: flex;
  justify-content: center;
}

// 淡入淡出动画
.fade-enter-active,
.fade-leave-active {
  transition: opacity 0.2s ease;
}

.fade-enter-from,
.fade-leave-to {
  opacity: 0;
}

// 作品信息区域
.work-info-section {
  background: #fafafa;
  border-radius: 8px;
  padding: 16px;
  margin-bottom: 24px;
}

.info-row {
  display: flex;
  align-items: flex-start;
  padding: 8px 0;
  border-bottom: 1px solid #f0f0f0;

  &:last-child {
    border-bottom: none;
  }
}

.info-label {
  width: 80px;
  flex-shrink: 0;
  color: rgba(0, 0, 0, 0.45);
  font-size: 14px;
}

.info-value {
  flex: 1;
  color: rgba(0, 0, 0, 0.85);
  font-size: 14px;
  word-break: break-word;

  &.description {
    white-space: pre-wrap;
    line-height: 1.6;
  }
}

// 附件区域
.attachments-section {
  margin-top: 24px;
}

.section-title {
  font-size: 14px;
  font-weight: 500;
  color: rgba(0, 0, 0, 0.85);
  margin-bottom: 12px;
}

.attachments-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.attachment-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px;
  border: 1px solid #d9d9d9;
  border-radius: 8px;
  transition: all 0.3s;

  &:hover {
    border-color: #1890ff;
    background: #f0f7ff;
  }
}

.attachment-info {
  display: flex;
  align-items: center;
  flex: 1;
  min-width: 0;
}

.attachment-icon {
  font-size: 16px;
  color: #1890ff;
  margin-right: 8px;
}

.attachment-name {
  font-size: 14px;
  color: rgba(0, 0, 0, 0.85);
  margin-right: 8px;
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.attachment-size {
  font-size: 12px;
  color: rgba(0, 0, 0, 0.45);
  white-space: nowrap;
}
</style>
