<template>
  <div ref="mod">
    <a-modal
      :get-container="() => $refs.mod"
      :open="open"
      :mask-closable="false"
      :width="600"
      @cancel="cancel"
      :footer="null"
    >
      <template #title>
        <div class="header">
          <div class="title">{{ title }}</div>
          <a-button type="link" @click="downloadTemplate">下载导入模板</a-button>
        </div>
      </template>
      <a-upload-dragger
        v-model:fileList="fileList"
        name="file"
        :multiple="false"
        :action="action"
        :accept="'.xlsx'"
        :headers="headers"
        :customRequest="customRequest"
        :before-upload="beforeUpload"
        @change="handleChange"
        @drop="handleDrop"
      >
        <p class="ant-upload-drag-icon">
          <inbox-outlined></inbox-outlined>
        </p>
        <p class="ant-upload-text">单击或拖动文件到此区域进行上传</p>
        <p class="ant-upload-hint">支持 .xlsx 格式文件，最大 5MB </p>
      </a-upload-dragger>

      <div v-if="repeateIds.length > 0" class="results">
        <div class="title">
          <span>以下设备ID重复，未被导入（共{{ repeateIds.length }}个）</span>
          <span class="copyBtn" @click="copyIdsHandler"> <CopyOutlined /> 复制全部ID</span>
        </div>
        <div class="itemBox">
          <div v-for="(item, index) in repeateIds" :key="index" class="item">
            {{ item }}
          </div>
        </div>
      </div>

      <div class="notes">
        <div class="title">导入说明</div>
        <div class="item"> • 文件表头：固件版本、设备ID、设备类型 </div>
        <div class="item"> • 设备ID：不能重复，重复的设备将被跳过 </div>
        <div class="item"> • 设备类型：LNA、LNB </div>
      </div>

      <div class="footer"> </div>
    </a-modal>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue'
import { message, type UploadChangeParam, Upload } from 'ant-design-vue'
import { InboxOutlined, CopyOutlined } from '@ant-design/icons-vue'
import { useUserStore } from '@/stores/user'
import axios, { type AxiosProgressEvent, type AxiosResponse } from 'axios'
import type { UploadRequestOption } from 'ant-design-vue/es/vc-upload/interface'
import { useClipboard } from '@vueuse/core'

defineOptions({
  name: 'addDevice',
})

const userStore = useUserStore()

type Props = {
  open: boolean
  title: string
}
const emit = defineEmits<{
  (e: 'update:open', value: boolean): void
  (e: 'success', value: void): void
}>()

// eslint-disable-next-line @typescript-eslint/no-unused-vars
const props = withDefaults(defineProps<Props>(), {
  open: false,
  title: '',
})

const fileList = ref([])
const action = `${import.meta.env.VITE_API_BASE_URL}/device/uploadDev`

const handleChange = (info: UploadChangeParam) => {
  console.log('handleChange', info)
  const status = info.file.status
  if (status !== 'uploading') {
    console.log(info.file, info.fileList)
  }
  if (status === 'done') {
    console.log(`${info.file.name} file uploaded successfully.`)
  } else if (status === 'error') {
    console.log(`${info.file.name} file upload failed.`)
  }
}

function handleDrop(e: DragEvent) {
  console.log(e)
}

const headers = {
  'content-type': 'multipart/form-data',
  Authorization: userStore.userInfo.tokenValue,
}

// 自定义上传文件类型（扩展原生 File 类型）
interface CustomUploadFile extends File {
  uid: string
  readonly lastModifiedDate: Date
  // webkitRelativePath?: string
}

// 进度回调函数类型
type UploadProgressHandler = (progressEvent: {
  percent: number
  loaded: number
  total: number
  event: ProgressEvent
}) => void

// 导入设备ID重复列表
const repeateIds = ref<string[]>([])
// 成功回调函数类型
// eslint-disable-next-line @typescript-eslint/no-explicit-any
type UploadSuccessHandler = <T = any>(response: T, event?: ProgressEvent) => void

const customRequest = (options: UploadRequestOption) => {
  const { file, onProgress, onSuccess } = options
  const customFile = file as CustomUploadFile

  // 创建 FormData
  const formData = new FormData()
  formData.append('file', customFile)

  // 处理进度事件
  const handleProgress: UploadProgressHandler = (progressEvent) => {
    // 确保进度在 0-100 范围内
    const percent = Math.min(100, Math.max(0, progressEvent.percent))
    onProgress?.({ percent })
  }

  // 处理成功响应
  const handleSuccess: UploadSuccessHandler = (response) => {
    onSuccess?.(response)
  }

  repeateIds.value = []
  // 发送请求
  axios
    .post(action, formData, {
      headers: { 'Content-Type': 'multipart/form-data' },
      onUploadProgress: (progressEvent: AxiosProgressEvent) => {
        if (!progressEvent.total) return

        const percent = Math.round((progressEvent.loaded * 100) / progressEvent.total)

        handleProgress({
          percent,
          loaded: progressEvent.loaded,
          total: progressEvent.total,
          event: progressEvent.event,
        })
      },
    })
    .then((response: AxiosResponse) => {
      handleSuccess(response.data)
      console.log('上传成功', response.data)
      const { suc, msg, msgList } = response.data.data
      if (suc) {
        message.success(msg)
      } else {
        message.error(msg)
      }
      repeateIds.value = msgList || []
    })
    .catch((error) => {
      options.onError?.(error)
    })

  return {
    abort() {
      console.log('上传取消', customFile.name)
    },
  }
}

const beforeUpload = (file: File) => {
  const isXLSX =
    file.type === 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' ||
    file.name.endsWith('.xlsx')
  if (!isXLSX) {
    message.error('只能上传XLSX格式的文件!')
    return Upload.LIST_IGNORE
  }

  const isLt5M = file.size / 1024 / 1024 <= 5
  if (!isLt5M) {
    message.error('文件大小不能超过5MB!')
    return Upload.LIST_IGNORE
  }

  return true
}

const downloadTemplate = () => {
  console.log('下载模板')
  const downloadLink = document.createElement('a')
  downloadLink.href = `/deviceTemplate.xlsx`
  downloadLink.download = '设备清单.xlsx'
  document.body.appendChild(downloadLink)
  downloadLink.click()
  document.body.removeChild(downloadLink)
}

const cancel = () => {
  fileList.value = []
  repeateIds.value = []
  emit('update:open', false)
}

const { copy } = useClipboard()
// 复制重复的ID
const copyIdsHandler = () => {
  copy(repeateIds.value.join('，'))
  message.success('复制成功')
}
</script>

<style scoped lang="less">
:deep(.ant-modal) {
  .header {
    display: flex;
    align-items: center;
  }

  .notes {
    background-color: #f7f7f7;
    padding: 16px;
    border-radius: 8px;
    margin-top: 24px;
    margin-top: 24px;

    .title {
      fonst-size: 16px;
      font-weight: 600;
    }
  }

  .results {
    background-color: #fff3cd;
    padding: 16px;
    border-radius: 8px;
    margin-top: 24px;
    margin-top: 24px;
    .title {
      font-size: 14px;
      font-weight: 600;
      color: #856404;
      display: flex;
      align-items: center;
      justify-content: space-between;

      .copyBtn {
        cursor: pointer;
        color: #856404;
        font-size: 14x;
        font-weight: 600;
        &:hover {
          color: #665103;
        }
      }
    }
    .itemBox {
      max-height: 200px;
      overflow-y: auto;
      margin-top: 8px;
      display: grid;
      grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
      gap: 8px;
      transition: max-height 0.3s ease;

      &::-webkit-scrollbar {
        width: 4px;
        height: 4px;
      }
      &::-webkit-scrollbar-thumb {
        background-color: #ccc;
        border-radius: 4px;
      }
    }

    .item {
      color: #856404;
    }
  }

  .footer {
    margin-top: 24px;
    text-align: right;
  }
}
</style>
