<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="work-preview-card">
          <div
            class="preview-wrapper"
            @mouseenter="showActions = true"
            @mouseleave="showActions = false"
          >
            <!-- 预览图 -->
            <img
              v-if="previewImageUrl"
              :src="previewImageUrl"
              alt="作品预览"
              class="preview-image"
              @error="handlePreviewError"
            />
            <div v-else class="preview-placeholder">
              <FileImageOutlined class="placeholder-icon" />
              <span>暂无预览图</span>
            </div>

            <!-- 悬浮操作按钮 -->
            <transition name="fade">
              <div v-show="showActions" class="actions-overlay">
                <div class="actions-buttons">
                  <a-button
                    v-if="workFile && is3DModelFile(workFile)"
                    type="primary"
                    @click="handlePreview3DModel(workFile)"
                  >
                    <template #icon><EyeOutlined /></template>
                    预览模型
                  </a-button>
                  <a-button
                    v-if="workFile"
                    @click="handleDownloadWork"
                  >
                    <template #icon><DownloadOutlined /></template>
                    下载作品
                  </a-button>
                </div>
              </div>
            </transition>
          </div>
        </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 showActions = ref(false)
const previewError = ref(false)

// 监听抽屉打开状态
watch(
  () => props.open,
  async (newVal) => {
    visible.value = newVal
    if (newVal) {
      previewError.value = false
      await fetchUserWork()
    } else {
      work.value = null
      showActions.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
  }
}

// 预览图 URL
const previewImageUrl = computed(() => {
  if (!work.value || previewError.value) return null

  // 优先使用 previewUrl
  if (work.value.previewUrl) {
    return getFileUrl(work.value.previewUrl)
  }

  return null
})

// 作品文件（只取第一个）
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 {
      return null
    }
  }

  if (!Array.isArray(files) || files.length === 0) return null

  // 处理可能是对象 {fileUrl: string} 或字符串的情况
  const firstFile = files[0]
  return typeof firstFile === "object" && firstFile?.fileUrl
    ? firstFile.fileUrl
    : firstFile
})

// 判断是否为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 = () => {
  previewError.value = true
}

// 预览3D模型
const handlePreview3DModel = (fileUrl: string) => {
  if (!fileUrl) {
    message.error("文件路径无效")
    return
  }
  const fullUrl = getFileUrl(fileUrl)
  const tenantCode = route.params.tenantCode as string
  router.push({
    path: `/${tenantCode}/workbench/model-viewer`,
    query: { url: fullUrl },
  })
}

// 下载作品
const handleDownloadWork = () => {
  if (!workFile.value) {
    message.error("无作品文件")
    return
  }
  const fileUrl = getFileUrl(workFile.value)
  const link = document.createElement("a")
  link.href = fileUrl
  link.download = work.value?.title || "作品"
  link.target = "_blank"
  document.body.appendChild(link)
  link.click()
  document.body.removeChild(link)
  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;
}

// 作品预览卡片
.work-preview-card {
  margin-bottom: 24px;
}

.preview-wrapper {
  position: relative;
  width: 100%;
  aspect-ratio: 1;
  border-radius: 12px;
  overflow: hidden;
  background: #f5f5f5;
  cursor: pointer;
}

.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: 64px;
    margin-bottom: 16px;
  }

  span {
    font-size: 14px;
  }
}

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

.actions-buttons {
  display: flex;
  flex-direction: column;
  gap: 12px;

  :deep(.ant-btn) {
    min-width: 140px;
  }
}

// 淡入淡出动画
.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>
