<script lang="ts" setup>
import { toast } from 'vue-sonner'
import { createResource } from '~/api/course'
import { uploadFile } from '~/api/file'
import type { FetchError, IResource } from '~/types'

const props = withDefaults(
  defineProps<{
    modelValue: boolean
    accept?: string
  }>(),
  {
    accept: '.docx, .pptx, .pdf, .png, .jpg, .mp4, .mp3',
  },
)

const emit = defineEmits<{
  'update:modelValue': [isOpen: boolean]
  'on-create': [resource: IResource]
}>()

const isDialogOpen = computed({
  get: () => props.modelValue,
  set: (value: boolean) => emit('update:modelValue', value),
})

const loginState = useLoginState()

// const isDialogOpen = ref(false);
const loading = ref(false)

const selectedFile = ref<File | null>(null)

const onUpload = async () => {
  if (!selectedFile.value) {
    toast.error('请先选择文件', { id: 'file-upload-error-no-file-selected' })
    return
  }
  loading.value = true

  toast.promise(
    new Promise((resolve, reject) => {
      uploadFile(selectedFile.value!, 'resource')
        .then((url) => {
          createResource({
            resourceName: selectedFile.value!.name,
            resourceSize: selectedFile.value!.size,
            resourceType: 'resource',
            resourceUrl: url,
            allowDownload: true,
            isRepo: false,
            ownerId: loginState.user.userId,
          })
            .then((result) => {
              if (result.code !== 200) {
                reject(new Error(result.msg || '文件上传失败'))
              }
              else {
                emit('on-create', {
                  id: result.resourceId,
                  resourceName: selectedFile.value!.name,
                  resourceSize: selectedFile.value!.size,
                  resourceType: 'resource',
                  resourceUrl: url,
                  allowDownload: true,
                  isRepo: false,
                  ownerId: loginState.user.userId,
                })
                resolve('文件上传成功')
              }
            })
            .catch((error) => {
              reject(error)
            })
        })
        .catch((error) => {
          reject(error)
        })
    }),
    {
      loading: '正在上传文件...',
      success: () => {
        isDialogOpen.value = false
        return '文件上传成功'
      },
      error: (error: FetchError) => {
        return error.message || '文件上传失败,请稍后重试'
      },
      finally: () => {
        loading.value = false
      },
    },
  )
}
</script>

<template>
  <Dialog v-model:open="isDialogOpen">
    <DialogTrigger as-child>
      <slot name="trigger" />
    </DialogTrigger>
    <DialogContent class="sm:max-w-[520px]">
      <DialogHeader>
        <DialogTitle>资源上传</DialogTitle>
        <DialogDescription>
          <p>上传资源文件并将其添加到课程中。</p>
          <p>
            支持的格式:<span class="font-medium">{{ accept }}</span>
          </p>
        </DialogDescription>
      </DialogHeader>
      <div class="flex flex-col gap-4">
        <FormField name="file">
          <FormItem>
            <FormLabel>选择文件</FormLabel>
            <FormControl>
              <Input
                type="file"
                :accept="accept"
                @change="(e: any) => {
                  const files = e.target.files;
                  if (files && files.length > 0) {
                    selectedFile = files[0];
                  }
                  else {
                    selectedFile = null;
                  }
                }"
              />
            </FormControl>
            <FormMessage />
          </FormItem>
        </FormField>
        <input
          type="hidden"
          name="courseId"
        />
        <div class="text-xs text-muted-foreground space-y-2">
          <p>
            根据国家《出版管理条例》《网络出版服务管理规定》及教育部《职业教育专业教学资源库建设工作手册》等相关规定,上传的资源必须符合以下要求:
          </p>
          <ul
            class="list-disc list-inside space-y-1 text-[11px] text-muted-foreground/80 text-justify"
          >
            <li>
              没有法律、法规禁止出版的内容,没有政治性、道德性问题和科学性错误,不泄露国家秘密。
            </li>
            <li>
              不含有侵犯他人著作权、肖像权、名誉权等权益的内容,资源具有原创性,引用需指明作者姓名、作品名称,使用他人作品应取得许可。
            </li>
            <li>
              采用法定计量单位,名词、术语、符号等符合国家统一规定,尚无统一规定的,可采用习惯用法并保持一致。
            </li>
            <li>
              地图具有严肃的政治性、严密的科学性和严格的法定性,使用的地图应根据《地图管理条例》的要求已送相关部门审核并标注审图号。
            </li>
            <li>不含有商业广告、商业性宣传内容。</li>
            <li>不含有色情、赌博、迷信、暴力等内容。</li>
          </ul>
        </div>
      </div>
      <DialogFooter>
        <Button
          :disabled="loading"
          @click="onUpload"
        >
          {{ loading ? "上传中..." : "上传" }}
        </Button>
      </DialogFooter>
    </DialogContent>
  </Dialog>
</template>

<style scoped></style>