<template>
  <div class="flex justify-center items-center size-full">
    <EdfsWrap title="固件上传" style="width: 50%; height: 50%">
      <el-upload v-model:fileList="fileList" v-loading="loading" element-loading-text="上传中..." drag action=""
        accept=".tar.gz" :limit="1" :on-exceed="handleExceed" :auto-upload="false" ref="uploadRef"
        class="h-[calc(100%-30px)] w-full">
        <div class="i-line-md:cloud-alt-upload-loop text-20px mx-auto"></div>
        <div class="text">拖拽文件或者 <em>点击上传</em></div>
        <template #tip v-if="!fileList.length">
          <div class="el-upload__tip">上传限制一个文件，新文件会覆盖旧文件</div>
        </template>
      </el-upload>
      <div class="flex justify-center">
        <el-button type="primary" @click="onSave" v-show="fileList.length && !loading">确定上传</el-button>
        <el-button type="info" v-show="loading" @click="onClone">取消上传</el-button>
      </div>
    </EdfsWrap>
  </div>
</template>

<script setup lang="ts">
import { uploadFirmwareFile } from '@/api/module/firmware'
import { useMessage } from '@/composables/useMessage'
import type {
  UploadInstance,
  UploadProps,
  UploadRawFile,
  UploadUserFile,
} from 'element-plus'

const message = useMessage()

const fileList = ref<UploadUserFile[]>([])

const upload = ref<UploadInstance>()
const handleExceed: UploadProps['onExceed'] = files => {
  upload.value!.clearFiles()
  const file = files[0] as UploadRawFile

  upload.value!.handleStart(file)
}

const uploadRef = ref<UploadInstance>()

const beforeAvatarUpload: UploadProps['beforeUpload'] = rawFile => {
  const accept = ['.zip', '.tar', '.tar.gz']
  const fileTypes = rawFile.name.substring(rawFile.name.indexOf('.'))

  if (!accept.includes(fileTypes)) {
    message.error('请上传 tar.gz 文件')
    uploadRef.value?.clearFiles?.()
    return false
  }
  return true
}
function validate() {
  if (!fileList.value.length) {
    message.error('请上传文件')
    return true
  }

  return beforeAvatarUpload(fileList.value[0].raw!)
}
const loading = ref(false)
const abortController = ref<AbortController>()

async function onSave() {
  if (loading.value) {
    message.error('文件正在上传中，请稍后')
    return
  }
  if (!validate()) return
  loading.value = true
  abortController.value = new AbortController()
  const data = new FormData()
  data.append('file', fileList.value[0].raw as File)
  const userFile = fileList.value[0] as UploadUserFile
  const res = await uploadFirmwareFile(data, abortController.value)
  if (res.code === 0) {
    message.success('上传成功')
  } else {
    message.error('上传失败')
  }
  // const file = userFile.raw as File
  // const fileName = userFile.name

  // const chunkList = await createChunksFromFileData(file, 1024)

  // try {
  //   for (const chunk of chunkList) {
  //     const { chunkData, offset } = chunk
  //     const res = await uploadSftpFile(
  //       {
  //         fileName,
  //         chunk: chunkData,
  //         targetPath: props.curPath,
  //         offset,
  //       },
  //       abortController.value
  //     )

  //     if (res.code === -777) {
  //       return
  //     }
  //     if (![200, 0].includes(res.code)) {
  //       // 如果是手动取消的请求，不提示错误
  //       message.error(`上传失败,${res.msg}`)
  //       return
  //     }
  //   }
  // } catch (error) {
  //   message.error('上传失败')
  // }
  abortController.value = undefined

  loading.value = false

  onClone()
}

async function readFileAsArrayBuffer(file: File): Promise<ArrayBuffer> {
  return new Promise((resolve, reject) => {
    const reader = new FileReader()
    reader.readAsArrayBuffer(file)
    reader.onload = () => resolve(reader.result as ArrayBuffer)
    reader.onerror = reject
  })
}

async function createChunksFromFileData(file: File, chunkSize: number) {
  const fileData = await readFileAsArrayBuffer(file)

  const chunkList: { offset: number; chunkIndex: number; chunkData: Uint8Array }[] = []
  let offset = 0
  let chunkIndex = 0

  while (offset < fileData.byteLength) {
    const chunkData = new Uint8Array(fileData.slice(offset, offset + chunkSize))
    chunkList.push({
      offset,
      chunkIndex,
      chunkData,
    })

    offset += chunkSize
    chunkIndex++
  }

  return chunkList
}

function clearData() {
  fileList.value = []
}
function onClone() {
  if (loading.value) {
    abortController.value?.abort()
    loading.value = false
  }
  clearData()
}
</script>

<style lang="scss" scoped>
:deep(.el-upload) {
  height: calc(100% - 50px);
  width: 100%;
}

:deep(.el-upload-dragger) {
  height: 100%;
  width: 100%;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
}
</style>
