<template>
  <a-modal
    :open="open"
    :title="isReviewed ? '查看评审' : '作品评审'"
    width="900px"
    :footer="null"
    @cancel="handleClose"
  >
    <a-spin :spinning="loading">
      <div class="review-work-modal">
        <!-- 作品信息 -->
        <a-card title="作品信息" size="small" class="mb-4">
          <a-descriptions :column="2" size="small">
            <a-descriptions-item label="作品编号">
              {{ workDetail?.workNo || '-' }}
            </a-descriptions-item>
            <a-descriptions-item label="作品名称">
              {{ workDetail?.title || '-' }}
            </a-descriptions-item>
            <a-descriptions-item label="参赛者">
              {{ workDetail?.registration?.user?.nickname || '-' }}
            </a-descriptions-item>
            <a-descriptions-item label="报名账号">
              {{ workDetail?.submitterAccountNo || workDetail?.registration?.user?.username || '-' }}
            </a-descriptions-item>
            <a-descriptions-item label="提交时间" :span="2">
              {{ formatDate(workDetail?.submitTime) }}
            </a-descriptions-item>
            <a-descriptions-item label="作品描述" :span="2">
              {{ workDetail?.description || '-' }}
            </a-descriptions-item>
          </a-descriptions>

          <!-- 作品附件 -->
          <div v-if="workDetail?.attachments?.length" class="attachments-section">
            <div class="section-title">作品附件</div>
            <div class="attachment-list">
              <a
                v-for="attachment in workDetail.attachments"
                :key="attachment.id"
                :href="attachment.fileUrl"
                target="_blank"
                class="attachment-item"
              >
                <FileOutlined />
                <span>{{ attachment.fileName }}</span>
              </a>
            </div>
          </div>

          <!-- 3D模型预览 -->
          <div v-if="has3DModel" class="model-preview-section">
            <div class="section-title">3D模型预览</div>
            <a-button type="primary" @click="handlePreview3D">
              <template #icon><EyeOutlined /></template>
              预览3D模型
            </a-button>
          </div>
        </a-card>

        <!-- 评分表单 -->
        <a-card title="评分" size="small">
          <a-form
            ref="formRef"
            :model="scoreForm"
            :rules="rules"
            layout="vertical"
          >
            <a-form-item label="评分" name="score">
              <a-input-number
                v-model:value="scoreForm.score"
                :min="0"
                :max="100"
                :precision="2"
                :disabled="isReviewed"
                style="width: 200px"
                placeholder="请输入分数（0-100）"
              />
              <span class="score-hint">满分100分</span>
            </a-form-item>
            <a-form-item label="评语" name="comments">
              <a-textarea
                v-model:value="scoreForm.comments"
                :rows="4"
                :disabled="isReviewed"
                placeholder="请输入评语（可选）"
                :maxlength="500"
                show-count
              />
            </a-form-item>
          </a-form>

          <div v-if="!isReviewed" class="form-actions">
            <a-button @click="handleClose">取消</a-button>
            <a-button type="primary" :loading="submitLoading" @click="handleSubmit">
              提交评分
            </a-button>
          </div>
        </a-card>
      </div>
    </a-spin>
  </a-modal>
</template>

<script setup lang="ts">
import { ref, reactive, watch, computed } from "vue"
import { useRoute, useRouter } from "vue-router"
import { message } from "ant-design-vue"
import type { FormInstance, Rule } from "ant-design-vue/es/form"
import { FileOutlined, EyeOutlined } from "@ant-design/icons-vue"
import dayjs from "dayjs"
import { worksApi, reviewsApi } from "@/api/contests"

const props = defineProps<{
  open: boolean
  assignmentId: number | null
  workId: number | null
}>()

const emit = defineEmits<{
  (e: "update:open", value: boolean): void
  (e: "success"): void
}>()

const route = useRoute()
const router = useRouter()
const tenantCode = route.params.tenantCode as string

// 表单引用
const formRef = ref<FormInstance>()

// 加载状态
const loading = ref(false)
const submitLoading = ref(false)

// 作品详情
const workDetail = ref<any>(null)

// 评分数据
const existingScore = ref<any>(null)

// 是否已评审
const isReviewed = computed(() => existingScore.value !== null)

// 评分表单
const scoreForm = reactive({
  score: undefined as number | undefined,
  comments: "",
})

// 表单验证规则
const rules: Record<string, Rule[]> = {
  score: [
    { required: true, message: "请输入评分", trigger: "blur" },
    { type: "number", min: 0, max: 100, message: "评分范围为0-100", trigger: "blur" },
  ],
}

// 是否有3D模型
const has3DModel = computed(() => {
  if (!workDetail.value?.attachments) return false
  return workDetail.value.attachments.some((a: any) =>
    ['.glb', '.gltf', '.obj', '.fbx', '.stl'].some(ext =>
      a.fileName?.toLowerCase().endsWith(ext) || a.fileUrl?.toLowerCase().endsWith(ext)
    )
  )
})

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

// 获取作品详情
const fetchWorkDetail = async () => {
  if (!props.workId) return

  loading.value = true
  try {
    const detail = await worksApi.getDetail(props.workId)
    workDetail.value = detail

    // 获取当前评委的评分记录
    const scores = await reviewsApi.getWorkScores(props.workId)
    // 找到当前分配记录对应的评分
    const myScore = scores.find((s: any) => s.assignmentId === props.assignmentId)
    if (myScore && myScore.score !== null) {
      existingScore.value = myScore
      scoreForm.score = Number(myScore.score)
      scoreForm.comments = myScore.comments || ""
    } else {
      existingScore.value = null
      scoreForm.score = undefined
      scoreForm.comments = ""
    }
  } catch (error: any) {
    message.error(error?.response?.data?.message || "获取作品详情失败")
  } finally {
    loading.value = false
  }
}

// 预览3D模型
const handlePreview3D = () => {
  if (!workDetail.value?.attachments) return

  const modelAttachment = workDetail.value.attachments.find((a: any) =>
    ['.glb', '.gltf', '.obj', '.fbx', '.stl'].some(ext =>
      a.fileName?.toLowerCase().endsWith(ext) || a.fileUrl?.toLowerCase().endsWith(ext)
    )
  )

  if (modelAttachment) {
    // 保存模型URL到sessionStorage
    sessionStorage.setItem('previewModelUrl', modelAttachment.fileUrl)
    // 打开新窗口预览
    window.open(`/${tenantCode}/workbench/model-viewer`, '_blank')
  }
}

// 提交评分
const handleSubmit = async () => {
  if (!props.assignmentId || !props.workId) return

  try {
    await formRef.value?.validate()
  } catch {
    return
  }

  submitLoading.value = true
  try {
    await reviewsApi.score({
      assignmentId: props.assignmentId,
      workId: props.workId,
      totalScore: scoreForm.score!,
      comments: scoreForm.comments || undefined,
    })
    message.success("评分提交成功")
    emit("success")
    handleClose()
  } catch (error: any) {
    message.error(error?.response?.data?.message || "提交失败")
  } finally {
    submitLoading.value = false
  }
}

// 关闭弹框
const handleClose = () => {
  emit("update:open", false)
}

// 监听弹框打开
watch(
  () => props.open,
  (val) => {
    if (val && props.workId) {
      fetchWorkDetail()
    } else {
      // 重置表单
      workDetail.value = null
      existingScore.value = null
      scoreForm.score = undefined
      scoreForm.comments = ""
    }
  }
)
</script>

<style scoped lang="scss">
.review-work-modal {
  max-height: 70vh;
  overflow-y: auto;
}

.mb-4 {
  margin-bottom: 16px;
}

.attachments-section,
.model-preview-section {
  margin-top: 16px;
  padding-top: 16px;
  border-top: 1px solid #f0f0f0;
}

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

.attachment-list {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.attachment-item {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 4px 12px;
  background: #f5f5f5;
  border-radius: 4px;
  color: #1890ff;
  text-decoration: none;
  transition: all 0.2s;

  &:hover {
    background: #e6f7ff;
  }
}

.score-hint {
  margin-left: 12px;
  color: #999;
  font-size: 12px;
}

.form-actions {
  display: flex;
  justify-content: flex-end;
  gap: 12px;
  margin-top: 16px;
  padding-top: 16px;
  border-top: 1px solid #f0f0f0;
}
</style>
