<script setup lang="ts">
import type { UploadFile, UploadProps } from 'ant-design-vue';

import type { PaperSubmitVO } from '#/api/outcome';

import { ref } from 'vue';

import { InboxOutlined } from '@ant-design/icons-vue';
import { Alert, message, Upload, UploadDragger } from 'ant-design-vue';

import { useEditShell } from '#/adapter/shell';
import { invokeMethod } from '#/adapter/vxe-table/proxy/invoke-method';
import { uploadFileMethod } from '#/api/common';
import { useWorkroomStore } from '#/stores';

import { paperForm } from '../paper.data';

const workroomStore = useWorkroomStore();

const PDF_MAX_SIZE = 20 * 1024 * 1024;

const pdfFileList = ref<UploadFile[]>([]);
const pdfUrl = ref<string>();
const pdfUploading = ref(false);

function createUploadFile(url: string | undefined, name: string): UploadFile[] {
  if (!url) return [];
  return [
    {
      uid: '-1',
      name,
      status: 'done',
      url,
    },
  ];
}

function resetUploads() {
  pdfFileList.value = [];
  pdfUrl.value = void 0;
  pdfUploading.value = false;
}

async function uploadImmediately(file: File) {
  const uploadFile: UploadFile = {
    uid: `${Date.now()}`,
    name: file.name,
    status: 'uploading',
    percent: 0,
  };
  pdfFileList.value = [uploadFile];
  pdfUploading.value = true;

  try {
    const url = await invokeMethod(uploadFileMethod(file), { force: true });
    if (!url) {
      throw new Error('upload empty url');
    }
    pdfUrl.value = url;
    pdfFileList.value = [
      {
        ...uploadFile,
        status: 'done',
        url,
      },
    ];
  } catch {
    pdfUrl.value = void 0;
    pdfFileList.value = [
      {
        ...uploadFile,
        status: 'error',
      },
    ];
    message.error(`${file.name} 上传失败，请重试`);
  } finally {
    pdfUploading.value = false;
  }
}

const { Form, Shell, api } = useEditShell<PaperSubmitVO>(paperForm, {
  onLoaded(model) {
    api.shell.setState({
      title: model.id ? '编辑论文' : '上传论文',
    });
  },
  handleLoad(model) {
    resetUploads();
    pdfUrl.value = model.pdfUrl;
    pdfFileList.value = createUploadFile(model.pdfUrl, '论文.pdf');
    return model;
  },
  handleSubmit(values) {
    const workroomId = values.workroomId || workroomStore.workroomId;
    if (!workroomId) {
      message.error('请先选择工作室');
      throw new Error('workroom required');
    }
    if (pdfUploading.value) {
      message.warning('文件上传中，请稍候');
      throw new Error('uploading');
    }
    if (!pdfUrl.value) {
      message.error('请上传论文PDF文件');
      throw new Error('pdf required');
    }

    return {
      ...values,
      workroomId,
      pdfUrl: pdfUrl.value,
    };
  },
  onClosed: resetUploads,
});

const beforePdfUpload: UploadProps['beforeUpload'] = (file) => {
  const isPdf =
    file.type === 'application/pdf' || file.name.toLowerCase().endsWith('.pdf');
  if (!isPdf) {
    message.error('仅支持PDF格式文件');
    return Upload.LIST_IGNORE;
  }
  if (file.size > PDF_MAX_SIZE) {
    message.error('文件大小不能超过20MB');
    return Upload.LIST_IGNORE;
  }
  void uploadImmediately(file);
  return false;
};

function onPdfRemove() {
  pdfUrl.value = void 0;
}
</script>

<template>
  <Shell>
    <div class="mx-4">
      <Form />

      <div class="pb-4">
        <div class="mb-2 text-sm">
          <span class="text-destructive mr-1">*</span>
          论文PDF文件
        </div>
        <UploadDragger
          v-model:file-list="pdfFileList"
          :before-upload="beforePdfUpload"
          :max-count="1"
          accept=".pdf,application/pdf"
          @remove="onPdfRemove"
        >
          <p class="ant-upload-drag-icon">
            <InboxOutlined />
          </p>
          <p class="ant-upload-text">点击上传或拖拽PDF文件到此处</p>
          <p class="ant-upload-hint">
            仅支持PDF格式文件，建议文件大小不超过20MB
          </p>
        </UploadDragger>
      </div>

      <Alert type="info" show-icon class="mb-4">
        <template #message>温馨提示</template>
        <template #description>
          <ul class="mb-0 list-disc pl-4 text-sm">
            <li>请确保论文内容符合学术规范和版权要求</li>
            <li>上传的PDF文件将用于在线预览和下载</li>
            <li>论文一经上传，将进入审核流程</li>
          </ul>
        </template>
      </Alert>
    </div>
  </Shell>
</template>
