<template>
  <a-drawer
    v-model:open="visible"
    title="参赛作品"
    placement="right"
    width="500px"
    :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="work-section">
          <div class="section-label">作品名称</div>
          <div class="section-content">{{ work.title }}</div>
        </div>

        <!-- 作品介绍 -->
        <div class="work-section">
          <div class="section-label">作品介绍</div>
          <div class="section-content description-text">
            {{ work.description || "暂无介绍" }}
          </div>
        </div>

        <!-- 参赛作品 -->
        <div class="work-section">
          <div class="section-label">参赛作品</div>
          <div class="work-file-container">
            <div v-if="workFile" class="work-image-item">
              <div
                class="image-wrapper"
                :class="{ 'is-hovering': isHovering }"
                @mouseenter="handleImageHover(workFile)"
                @mouseleave="handleImageLeave"
              >
                <img
                  v-if="isImageFile(workFile)"
                  :src="getFileUrl(workFile)"
                  alt="作品图片"
                  class="work-image"
                  @error="handleImageError"
                />
                <div
                  v-else-if="is3DModelFile(workFile)"
                  class="file-placeholder model-file"
                >
                  <FileOutlined class="file-icon" />
                  <span class="file-name">{{ getFileName(workFile) }}</span>
                  <a-button
                    type="primary"
                    size="small"
                    class="preview-btn"
                    :class="{ 'btn-visible': isHovering }"
                    @click.stop="handlePreview3DModel(workFile)"
                  >
                    <template #icon><EyeOutlined /></template>
                    预览3D模型
                  </a-button>
                </div>
                <div v-else class="file-placeholder">
                  <FileOutlined class="file-icon" />
                  <span class="file-name">{{ getFileName(workFile) }}</span>
                </div>
                <!-- 图片预览按钮遮罩 -->
                <div
                  v-if="isImageFile(workFile) && isHovering"
                  class="preview-overlay"
                >
                  <a-button
                    type="primary"
                    size="large"
                    class="preview-overlay-btn"
                    @click.stop="handlePreviewImage(workFile)"
                  >
                    <template #icon><EyeOutlined /></template>
                    预览图片
                  </a-button>
                </div>
              </div>
              <!-- 图片预览遮罩 -->
              <div
                v-if="previewImage && previewImage === workFile"
                class="image-preview-overlay"
                @mouseleave="handleImageLeave"
              >
                <img
                  :src="getFileUrl(workFile)"
                  alt="作品预览"
                  class="preview-image"
                />
              </div>
            </div>
            <div v-else class="no-files">暂无作品文件</div>
          </div>
        </div>

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

        <!-- 上传的附件 -->
        <div
          v-if="work.attachments && work.attachments.length > 0"
          class="work-section"
        >
          <div class="section-label">上传附件</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-space>
        <a-button @click="handleCancel">关闭</a-button>
      </a-space>
    </template>
  </a-drawer>
</template>

<script setup lang="ts">
import { ref, watch, computed } from "vue"
import { useRouter } from "vue-router"
import { message } from "ant-design-vue"
import {
  FileOutlined,
  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 authStore = useAuthStore()
const visible = ref(false)
const loading = ref(false)
const work = ref<ContestWork | null>(null)
const previewImage = ref<string | null>(null)
const isHovering = ref(false)

// 监听抽屉打开状态
watch(
  () => props.open,
  async (newVal) => {
    visible.value = newVal
    if (newVal) {
      await fetchUserWork()
    } else {
      work.value = null
      previewImage.value = null
      isHovering.value = false
    }
  },
  { 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 registrationResponse = await registrationsApi.getList({
      contestId: props.contestId,
      userId: userId,
      registrationType: "individual",
      registrationState: "passed",
      page: 1,
      pageSize: 10,
    })

    if (registrationResponse.list.length === 0) {
      message.warning("您尚未报名该赛事或报名未通过，无法查看作品")
      visible.value = false
      return
    }

    const registrationId = registrationResponse.list[0].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
  }
}

// 作品文件（只取第一个）
const workFile = computed(() => {
  if (!work.value) return null

  let files = work.value.files || []

  // 如果 files 是字符串（JSON），尝试解析
  if (typeof files === "string") {
    try {
      files = JSON.parse(files)
    } catch (e) {
      console.error("解析文件列表失败:", e)
      files = []
    }
  }

  // 确保 files 是数组
  if (!Array.isArray(files)) {
    files = []
  }

  const file = files.length > 0 ? files[0] : null

  // 调试信息
  if (file) {
    console.log("当前文件:", file)
    console.log("是否为图片:", isImageFile(file))
    console.log("是否为3D模型:", is3DModelFile(file))
  }

  return file
})

// 判断是否为图片文件
const isImageFile = (fileUrl: string | null): boolean => {
  if (!fileUrl || typeof fileUrl !== "string") return false

  const imageExtensions = [
    ".jpg",
    ".jpeg",
    ".png",
    ".gif",
    ".bmp",
    ".webp",
    ".svg",
  ]
  const lowerUrl = fileUrl.toLowerCase()
  return imageExtensions.some((ext) => lowerUrl.includes(ext))
}

// 判断是否为3D模型文件
const is3DModelFile = (fileUrl: string | null): boolean => {
  if (!fileUrl || typeof fileUrl !== "string") return false

  const modelExtensions = [
    ".glb",
    ".gltf",
    ".obj",
    ".fbx",
    ".3ds",
    ".dae",
    ".stl",
    ".ply",
  ]
  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 || ""
  // 如果 fileUrl 已经以 /api 开头，且 baseURL 也包含 /api，需要避免重复
  if (fileUrl.startsWith("/api") && baseURL.includes("/api")) {
    // fileUrl 已经包含 /api，直接拼接 baseURL 的协议和域名部分
    const urlWithoutApi = baseURL.replace(/\/api$/, "")
    return `${urlWithoutApi}${fileUrl}`
  }
  // 正常拼接
  return `${baseURL}${fileUrl.startsWith("/") ? "" : "/"}${fileUrl}`
}

// 获取文件名
const getFileName = (fileUrl: string): string => {
  if (!fileUrl) return "文件"

  try {
    // 移除查询参数和锚点
    const urlWithoutQuery = fileUrl.split("?")[0].split("#")[0]

    // 提取文件名
    const parts = urlWithoutQuery.split("/")
    let fileName = parts[parts.length - 1] || "文件"

    // 如果文件名是空的或者是特殊字符，返回默认值
    if (!fileName || fileName.trim() === "" || fileName === "[") {
      return "文件"
    }

    // 解码 URL 编码的文件名
    try {
      fileName = decodeURIComponent(fileName)
    } catch {
      // 如果解码失败，使用原始文件名
    }

    // 如果文件名太长，截断并添加省略号
    const maxLength = 20
    if (fileName.length > maxLength) {
      const ext = fileName.substring(fileName.lastIndexOf("."))
      const nameWithoutExt = fileName.substring(0, fileName.lastIndexOf("."))
      if (nameWithoutExt.length > maxLength - ext.length - 3) {
        return (
          nameWithoutExt.substring(0, maxLength - ext.length - 3) + "..." + ext
        )
      }
    }

    return fileName
  } catch (error) {
    console.error("获取文件名失败:", error)
    return "文件"
  }
}

// 图片鼠标移入
const handleImageHover = (file: string | null) => {
  if (!file) return

  console.log("鼠标移入，文件:", file)
  console.log("isHovering 设置为 true")
  isHovering.value = true

  if (isImageFile(file)) {
    previewImage.value = file
  }
}

// 图片鼠标移出
const handleImageLeave = () => {
  isHovering.value = false
  previewImage.value = null
}

// 图片加载错误
const handleImageError = (event: Event) => {
  const img = event.target as HTMLImageElement
  img.style.display = "none"
}

// 下载附件
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 (error: any) {
    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"] || "未知"
}

// 预览3D模型 - 跳转到全屏页面
const handlePreview3DModel = (fileUrl: string) => {
  if (!fileUrl) {
    message.error("文件路径无效")
    return
  }
  const fullUrl = getFileUrl(fileUrl)
  console.log("预览3D模型，文件URL:", fullUrl)

  // 直接使用 location 跳转
  const viewerUrl = `/model-viewer?url=${encodeURIComponent(fullUrl)}`
  console.log("跳转URL:", viewerUrl)
  window.location.href = viewerUrl
}

// 预览图片
const handlePreviewImage = (fileUrl: string) => {
  previewImage.value = fileUrl
}

// 取消
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;
}

.work-section {
  margin-bottom: 24px;

  &:last-child {
    margin-bottom: 0;
  }
}

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

.section-content {
  font-size: 14px;
  color: rgba(0, 0, 0, 0.65);
  line-height: 1.6;
}

.description-text {
  white-space: pre-wrap;
  word-break: break-word;
}

.work-file-container {
  display: flex;
  justify-content: flex-start;
}

.work-image-item {
  position: relative;
  width: 400px;
  height: 400px;
}

.image-wrapper {
  width: 100%;
  height: 100%;
  border: 1px solid #d9d9d9;
  border-radius: 4px;
  overflow: hidden;
  cursor: pointer;
  transition: all 0.3s;
  background: #fafafa;
  position: relative;

  &:hover,
  &.is-hovering {
    border-color: #1890ff;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
  }
}

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

.file-placeholder {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 16px;
  color: rgba(0, 0, 0, 0.45);
  position: relative;

  &.model-file {
    padding-bottom: 60px;
  }
}

.file-icon {
  font-size: 48px;
  margin-bottom: 8px;
}

.file-name {
  font-size: 12px;
  text-align: center;
  word-break: break-word;
  overflow-wrap: break-word;
  margin-bottom: 8px;
  max-width: 100%;
  padding: 0 4px;
  line-height: 1.4;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.preview-btn {
  position: absolute;
  bottom: 12px;
  left: 50%;
  transform: translateX(-50%);
  opacity: 0.7;
  transition: all 0.3s ease-in-out;
  z-index: 10;

  &.btn-visible,
  &:hover {
    opacity: 1;
    transform: translateX(-50%) scale(1.05);
  }
}

.preview-overlay {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.5);
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 4px;
  animation: fadeIn 0.3s ease-in-out;
  z-index: 10;
}

.preview-overlay-btn {
  animation: scaleIn 0.3s ease-in-out;
}

@keyframes fadeIn {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

@keyframes scaleIn {
  from {
    transform: scale(0.8);
    opacity: 0;
  }
  to {
    transform: scale(1);
    opacity: 1;
  }
}

.image-preview-overlay {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.8);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 10000;
  cursor: zoom-out;
}

.preview-image {
  max-width: 90%;
  max-height: 90%;
  object-fit: contain;
}

.no-files {
  color: rgba(0, 0, 0, 0.45);
  font-size: 14px;
  padding: 20px 0;
}

.work-info {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.info-item {
  display: flex;
  align-items: center;
  font-size: 14px;
}

.info-label {
  color: rgba(0, 0, 0, 0.65);
  margin-right: 8px;
  min-width: 80px;
}

.info-value {
  color: rgba(0, 0, 0, 0.85);
}

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

.attachment-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px;
  border: 1px solid #d9d9d9;
  border-radius: 4px;
  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>
