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

    <a-form
      ref="formRef"
      :model="form"
      :rules="rules"
      :label-col="{ span: 6 }"
      :wrapper-col="{ span: 18 }"
      layout="horizontal"
    >
      <a-form-item label="作品名称" name="title" required>
        <a-input
          v-model:value="form.title"
          placeholder="请输入作品名称"
          :maxlength="200"
        />
      </a-form-item>

      <a-form-item label="作品介绍" name="description" required>
        <a-textarea
          v-model:value="form.description"
          placeholder="请输入作品介绍"
          :rows="6"
          :maxlength="2000"
          show-count
        />
      </a-form-item>

      <a-form-item label="上传作品" name="workFile" required>
        <a-upload
          v-model:file-list="workFileList"
          :before-upload="handleBeforeUploadWork"
          :remove="handleRemoveWork"
          :accept="workAcceptTypes"
          :max-count="1"
        >
          <a-button>
            <template #icon><UploadOutlined /></template>
            选择
          </a-button>
          <template #tip>
            <div class="upload-tip">
              支持3D文件格式：.obj, .fbx, .3ds, .dae, .blend, .max, .c4d, .stl,
              .ply, .gltf, .glb
            </div>
          </template>
        </a-upload>
      </a-form-item>

      <a-form-item label="上传附件">
        <a-upload
          v-model:file-list="attachmentFileList"
          :before-upload="handleBeforeUploadAttachment"
          :remove="handleRemoveAttachment"
          :max-count="5"
        >
          <a-button>
            <template #icon><UploadOutlined /></template>
            上传
          </a-button>
        </a-upload>
      </a-form-item>
    </a-form>

    <template #footer>
      <a-space>
        <a-button @click="handleCancel">取消</a-button>
        <a-button type="primary" :loading="submitLoading" @click="handleSubmit">
          确定
        </a-button>
      </a-space>
    </template>
  </a-drawer>
</template>

<script setup lang="ts">
import { ref, reactive, watch } from "vue"
import { message } from "ant-design-vue"
import { UploadOutlined } from "@ant-design/icons-vue"
import type { FormInstance, UploadFile } from "ant-design-vue"
import { worksApi, registrationsApi, type SubmitWorkForm } from "@/api/contests"
import { useAuthStore } from "@/stores/auth"
import request from "@/utils/request"

interface Props {
  open: boolean
  contestId: number
}

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

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

const authStore = useAuthStore()
const visible = ref(false)
const submitLoading = ref(false)
const formRef = ref<FormInstance>()

// 3D文件格式
const workAcceptTypes =
  ".obj,.fbx,.3ds,.dae,.blend,.max,.c4d,.stl,.ply,.gltf,.glb"

const form = reactive<{
  title: string
  description: string
  workFile: File | null
  attachmentFiles: File[]
}>({
  title: "",
  description: "",
  workFile: null,
  attachmentFiles: [],
})

const workFileList = ref<UploadFile[]>([])
const attachmentFileList = ref<UploadFile[]>([])

// 表单验证规则
const rules = {
  title: [{ required: true, message: "请输入作品名称", trigger: "blur" }],
  description: [{ required: true, message: "请输入作品介绍", trigger: "blur" }],
  workFile: [
    {
      required: true,
      validator: () => {
        if (!form.workFile) {
          return Promise.reject(new Error("请上传作品文件"))
        }
        return Promise.resolve()
      },
      trigger: "change",
    },
  ],
}

watch(
  () => props.open,
  (newVal) => {
    visible.value = newVal
    if (newVal) {
      resetForm()
      fetchRegistrationId()
    }
  },
  { immediate: true }
)

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

// 获取报名记录ID
const registrationIdRef = ref<number | null>(null)

const fetchRegistrationId = async () => {
  if (!authStore.user?.id) {
    message.error("用户未登录")
    return
  }

  try {
    const response = await registrationsApi.getList({
      contestId: props.contestId,
      userId: authStore.user.id,
      page: 1,
      pageSize: 1,
    })

    if (response.list && response.list.length > 0) {
      const registration = response.list[0]
      if (registration.registrationState === "passed") {
        registrationIdRef.value = registration.id
      } else {
        message.warning("您的报名尚未通过审核，无法上传作品")
        visible.value = false
      }
    } else {
      message.warning("您尚未报名该赛事，无法上传作品")
      visible.value = false
    }
  } catch (error: any) {
    message.error(error?.response?.data?.message || "获取报名信息失败")
    visible.value = false
  }
}

// 上传作品前验证
const handleBeforeUploadWork = (file: File): boolean => {
  const fileName = file.name.toLowerCase()
  const validExtensions = [
    ".obj",
    ".fbx",
    ".3ds",
    ".dae",
    ".blend",
    ".max",
    ".c4d",
    ".stl",
    ".ply",
    ".gltf",
    ".glb",
  ]

  const isValid = validExtensions.some((ext) => fileName.endsWith(ext))

  if (!isValid) {
    message.error(
      "请上传3D文件格式（.obj, .fbx, .3ds, .dae, .blend, .max, .c4d, .stl, .ply, .gltf, .glb）"
    )
    return false
  }

  // 检查文件大小（限制为500MB）
  const maxSize = 500 * 1024 * 1024 // 500MB
  if (file.size > maxSize) {
    message.error("文件大小不能超过500MB")
    return false
  }

  form.workFile = file
  return false // 阻止自动上传
}

// 移除作品文件
const handleRemoveWork = () => {
  form.workFile = null
  return true
}

// 上传附件前验证
const handleBeforeUploadAttachment = (file: File): boolean => {
  // 检查文件大小（限制为100MB）
  const maxSize = 100 * 1024 * 1024 // 100MB
  if (file.size > maxSize) {
    message.error("附件大小不能超过100MB")
    return false
  }

  form.attachmentFiles.push(file)
  return false // 阻止自动上传
}

// 移除附件
const handleRemoveAttachment = (file: UploadFile) => {
  const index = form.attachmentFiles.findIndex(
    (f) => f.name === file.name && f.size === file.size
  )
  if (index > -1) {
    form.attachmentFiles.splice(index, 1)
  }
  return true
}

// 重置表单
const resetForm = () => {
  form.title = ""
  form.description = ""
  form.workFile = null
  form.attachmentFiles = []
  workFileList.value = []
  attachmentFileList.value = []
  formRef.value?.resetFields()
}

// 提交表单
const handleSubmit = async () => {
  if (!formRef.value) return

  try {
    await formRef.value.validate()

    if (!registrationIdRef.value) {
      message.error("无法获取报名记录，请重新打开")
      return
    }

    if (!form.workFile) {
      message.error("请上传作品文件")
      return
    }

    submitLoading.value = true

    // 上传文件并获取URL
    const workFileUrls: string[] = []
    const attachmentUrls: string[] = []

    // 上传作品文件
    if (form.workFile) {
      try {
        const workUrl = await uploadFile(form.workFile)
        workFileUrls.push(workUrl)
      } catch (error: any) {
        message.error("作品文件上传失败：" + (error?.message || "未知错误"))
        submitLoading.value = false
        return
      }
    }

    // 上传附件
    for (const file of form.attachmentFiles) {
      try {
        const url = await uploadFile(file)
        attachmentUrls.push(url)
      } catch (error: any) {
        console.error("附件上传失败:", error)
        // 附件上传失败不影响主流程，只记录错误
      }
    }

    const submitData: SubmitWorkForm = {
      registrationId: registrationIdRef.value,
      title: form.title,
      description: form.description,
      files: [...workFileUrls, ...attachmentUrls],
    }

    await worksApi.submit(submitData)

    message.success("作品提交成功")
    emit("success")
    visible.value = false
    resetForm()
  } catch (error: any) {
    if (error?.errorFields) {
      // 表单验证错误
      return
    }
    message.error(error?.response?.data?.message || "作品提交失败")
  } finally {
    submitLoading.value = false
  }
}

// 文件上传函数
const uploadFile = async (file: File): Promise<string> => {
  const formData = new FormData()
  formData.append("file", file)

  try {
    // 使用文件上传接口
    const response = await request.post<any>("/upload", formData, {
      headers: {
        "Content-Type": "multipart/form-data",
      },
    })

    // 返回文件URL
    if (response && typeof response === "object" && "url" in response) {
      return String(response.url)
    }

    throw new Error("文件上传返回格式不正确")
  } catch (error: any) {
    console.error("文件上传失败:", error)
    throw new Error(error?.response?.data?.message || "文件上传失败")
  }
}

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

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

.upload-tip {
  margin-top: 8px;
  font-size: 12px;
  color: #8c8c8c;
}

:deep(.ant-upload-list) {
  margin-top: 8px;
}
</style>
