<template>
  <GiPageLayout>
    <div class="data-preprocessing-container">
      <!-- 上传进度框 -->
      <div v-if="uploadState.visible" class="upload-progress-fixed">
        <a-card :title="`上传进度 (${uploadState.percent}%)`" :bordered="false">
          <a-progress
              :percent="uploadState.percent"
              :status="uploadState.status"
              :stroke-width="16"
          />
          <div class="progress-details">
            <p><icon-file /> {{ uploadState.currentFile || '准备中...' }}</p>
            <p><icon-check-circle /> 已完成 {{ uploadState.uploadedCount }}/{{ uploadState.totalCount }}</p>
            <p><icon-clock-circle /> 状态: {{ getStatusText(uploadState.status) }}</p>
          </div>
        </a-card>
      </div>

      <div class="step-panel">
        <div class="step-header">
          <h3>批量上传图片</h3>
        </div>

        <div class="data-selection">
          <a-form :model="form" layout="vertical">
            <!-- 项目选择 -->
            <a-form-item label="所属项目" required>
              <a-select
                  v-model="form.projectId"
                  placeholder="请选择项目"
                  allow-search
                  :filter-option="filterProjectOption"
              >
                <a-option
                    v-for="project in projectList"
                    :key="project.id"
                    :value="project.id"
                    :label="project.name"
                />
              </a-select>
            </a-form-item>

            <!-- 图片来源选择 -->
            <a-form-item label="图片来源" required>
              <a-select
                  v-model="form.imageSource"
                  placeholder="请选择图片来源"
                  allow-search
                  :filter-option="filterSourceOption"
              >
                <a-option
                    v-for="source in imageSources"
                    :key="source.value"
                    :value="source.value"
                    :label="source.label"
                />
              </a-select>
            </a-form-item>

            <!-- 文件夹操作 -->
            <a-form-item label="文件操作">
              <div class="folder-actions">
                <a-upload
                    ref="uploadRef"
                    directory
                    :multiple="true"
                    :show-file-list="false"
                    accept="image/*"
                    :key="uploadKey"
                    @change="handleFolderSelect"
                >
                  <template #upload-button>
                    <a-button type="outline">
                      <template #icon>
                        <icon-folder />
                      </template>
                      选择文件夹
                    </a-button>
                  </template>
                </a-upload>
                <a-button
                    type="outline"
                    status="warning"
                    @click="clearFileList"
                    :disabled="selectedFiles.length === 0"
                >
                  <template #icon>
                    <icon-delete />
                  </template>
                  清空列表
                </a-button>
                <a-button
                    type="primary"
                    :loading="uploading"
                    :disabled="!canUpload"
                    @click="handleUpload"
                >
                  <template #icon>
                    <icon-upload />
                  </template>
                  开始上传
                </a-button>
              </div>
            </a-form-item>

            <!-- 文件列表 -->
            <a-form-item v-if="selectedFiles.length > 0">
              <div class="file-list-container">
                <div class="file-list-header">
                  <span>已选择 {{ selectedFiles.length }} 个文件（选中 {{ checkedFiles.length }} 个）</span>
                  <a-checkbox
                      v-model="selectAll"
                      :indeterminate="indeterminate"
                      @change="handleSelectAllChange"
                  >
                    全选
                  </a-checkbox>
                </div>

                <div class="file-table-wrapper">
                  <a-table
                      :data="selectedFiles"
                      :columns="fileColumns"
                      :row-selection="rowSelection"
                      :pagination="false"
                      row-key="uid"
                      size="small"
                      bordered
                  >
                    <!-- 表格列模板 -->
                    <template #thumbnail="{ record }">
                      <div class="thumbnail-cell">
                        <img
                            v-if="isImage(record.type)"
                            :src="record.preview"
                            class="thumbnail-image"
                            alt="预览"
                        />
                        <div v-else class="file-icon">
                          <icon-file />
                        </div>
                      </div>
                    </template>
                    <template #fileType="{ record }">
                      <a-tag :color="getFileTypeColor(record.type)" size="small">
                        {{ record.type }}
                      </a-tag>
                    </template>
                    <template #fileSize="{ record }">
                      {{ formatFileSize(record.size) }}
                    </template>
                  </a-table>
                </div>
              </div>
            </a-form-item>
          </a-form>
        </div>
      </div>
    </div>
  </GiPageLayout>
</template>

<script setup lang="ts">
import { ref, reactive, computed, nextTick } from 'vue'
import { Message } from '@arco-design/web-vue'
import type { UploadItem } from '@arco-design/web-vue/es/upload'
import type { SelectOptionData, TableColumnData, TableRowSelection } from '@arco-design/web-vue'
import axios from 'axios'

import {
  getProjectList,
  getImageSources
} from '@/apis/industrial-image'

// 类型定义
interface FileItem {
  uid: string
  name: string
  type: string
  size: number
  file: File
  preview?: string
}

type UploadStatus = 'waiting' | 'uploading' | 'success' | 'error'

// 数据状态
const projectList = ref([])

const imageSources = ref([])

// 获取项目列表
const fetchProjectList = async () => {
  try {
    const res = await getProjectList({ page: 1, pageSize: 1000 });
    projectList.value = res.data.map(item => ({
      name: item.projectName,
      id: item.projectId
    }))
  } catch (error) {
    Message.error('获取项目列表失败')
  } finally {
  }
}

// 获取图片来源
const fetchImageSourceList = async () => {
  try {
    const res = await getImageSources();
    res.data.forEach(item => {
      const key = Object.keys(item)[0];
      const value = item[key];
      imageSources.value.push({
        label: value,
        value:key
      });
    });
  } catch (error) {
    Message.error('获取项目列表失败')
  } finally {
  }
}

const form = reactive({
  projectId: undefined as number | undefined,
  imageSource: undefined as string | undefined
})

const selectedFiles = ref<FileItem[]>([])
const checkedFiles = ref<string[]>([])
const uploading = ref(false)
const uploadRef = ref()
const uploadKey = ref(0)

const uploadState = reactive({
  visible: false,
  percent: 0,
  status: 'waiting' as UploadStatus,
  currentFile: '',
  uploadedCount: 0,
  totalCount: 0
})

// 计算属性
const canUpload = computed(() => {
  return checkedFiles.value.length > 0
      && !!form.projectId
      && !!form.imageSource
      && !uploading.value
})

const selectAll = ref(false)
const indeterminate = computed(() => {
  return checkedFiles.value.length > 0 &&
      checkedFiles.value.length < selectedFiles.value.length
})

// 表格列配置
const fileColumns: TableColumnData[] = [
  {
    title: '选择',
    dataIndex: 'selection',
    type: 'selection',
    width: 60,
    align: 'center'
  },
  {
    title: '预览',
    dataIndex: 'thumbnail',
    slotName: 'thumbnail',
    width: 100,
    align: 'center'
  },
  {
    title: '文件名',
    dataIndex: 'name',
    ellipsis: true,
    tooltip: true,
    width: 300
  },
  {
    title: '类型',
    dataIndex: 'type',
    slotName: 'fileType',
    width: 100,
    align: 'center'
  },
  {
    title: '大小',
    dataIndex: 'size',
    slotName: 'fileSize',
    width: 100,
    align: 'center'
  }
]

// 行选择配置
const rowSelection = reactive<TableRowSelection>({
  type: 'checkbox',
  showCheckedAll: false,
  selectedRowKeys: checkedFiles,
  onChange: (rowKeys: string[]) => {
    checkedFiles.value = rowKeys
    selectAll.value = rowKeys.length === selectedFiles.value.length
  }
})

// 搜索过滤函数
const filterProjectOption = (inputValue: string, option: SelectOptionData) => {
  return option.label.toLowerCase().includes(inputValue.toLowerCase())
}

const filterSourceOption = (inputValue: string, option: SelectOptionData) => {
  return option.label.toLowerCase().includes(inputValue.toLowerCase())
}

// 文件选择处理
const handleFolderSelect = async (fileList: UploadItem[]) => {
  // 1. 清空现有状态
  clearFileList()

  // 2. 处理新文件
  const newFiles: FileItem[] = []
  for (const item of fileList) {
    const file = item.file
    if (!file) continue

    const fileType = file.type.split('/')[0] || 'unknown'
    const preview = fileType === 'image' ? URL.createObjectURL(file) : undefined

    newFiles.push({
      uid: item.uid,
      name: file.name,
      type: fileType,
      size: file.size,
      file: file,
      preview: preview
    })
  }

  // 3. 更新状态
  selectedFiles.value = newFiles
  checkedFiles.value = newFiles.map(f => f.uid)
  selectAll.value = true

  // 4. 重置上传组件（通过改变key强制重新创建组件）
  uploadKey.value++
}

// 清空文件列表
const clearFileList = () => {
  // 释放预览URL
  selectedFiles.value.forEach(file => {
    if (file.preview) URL.revokeObjectURL(file.preview)
  })

  // 重置状态
  selectedFiles.value = []
  checkedFiles.value = []
  selectAll.value = false
}

// 处理全选变化
const handleSelectAllChange = (checked: boolean) => {
  checkedFiles.value = checked ? selectedFiles.value.map(f => f.uid) : []
}

// 上传处理
const handleUpload = async () => {
  if (!canUpload.value) {
    Message.error('请完成所有必填项并选择文件')
    return
  }

  // 重置上传状态
  Object.assign(uploadState, {
    visible: true,
    percent: 0,
    status: 'uploading',
    currentFile: '',
    uploadedCount: 0,
    totalCount: checkedFiles.value.length
  })

  uploading.value = true

  try {
    const filesToUpload = selectedFiles.value.filter(f => checkedFiles.value.includes(f.uid))

    const formData = new FormData()

    // 添加所有图片文件到FormData
    filesToUpload.forEach(file => {
      formData.append('files', file);
    });

    let url =`http://pms.dtyx.net:9158/image/${form.projectId}/${form.imageSource}/upload-batch`;
    let res = await axios.post(
        url,
        formData,
        {
          onUploadProgress: (progressEvent) => {
            if (progressEvent.total) {
              uploadedBytes = progressEvent.loaded
              const elapsedTime = (Date.now() - startTime) / 1000
              const speed = uploadedBytes / elapsedTime
              uploadState.speed = `${formatFileSize(speed)}/s`

              const remainingBytes = totalBytes - uploadedBytes
              uploadState.remainingTime = formatTime(remainingBytes / speed)

              uploadState.percent = Math.round((uploadedBytes / totalBytes) * 100)
            }
          },
          headers: {
            'Content-Type': 'multipart/form-data'
          }
        }
    )
    console.log("res:",res);
    uploadState.status = 'success'
    Message.success(`成功上传 ${filesToUpload.length} 个文件`)
  } catch (error) {
    uploadState.status = 'error'
    Message.error('上传失败: ' + (error as Error).message)
  } finally {
    uploading.value = false
    // 5秒后自动隐藏进度框
    setTimeout(() => uploadState.visible = false, 5000)
  }
}

// 辅助函数
const getStatusText = (status: UploadStatus) => {
  const statusMap = {
    waiting: '等待上传',
    uploading: '上传中',
    success: '上传成功',
    error: '上传失败'
  }
  return statusMap[status] || status
}

const getFileTypeColor = (type: string) => {
  const colors: Record<string, string> = {
    image: 'arcoblue',
    video: 'green',
    audio: 'orange',
    document: 'purple'
  }
  return colors[type.toLowerCase()] || 'gray'
}

const formatFileSize = (bytes: number) => {
  if (bytes === 0) return '0 B'
  const k = 1024
  const sizes = ['B', 'KB', 'MB', 'GB']
  const i = Math.floor(Math.log(bytes) / Math.log(k))
  return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]
}

const isImage = (type: string) => type === 'image'

// 在组件挂载时获取项目列表
onMounted(() => {
  fetchProjectList()
  fetchImageSourceList()
})
</script>

<style scoped lang="less">
.data-preprocessing-container {
  position: relative;
  padding: 20px;
  min-height: calc(100vh - 40px);
}

.step-panel {
  background: #fff;
  border-radius: 8px;
  padding: 24px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

.step-header {
  margin-bottom: 24px;
  border-bottom: 1px solid var(--color-border);
  padding-bottom: 16px;

  h3 {
    margin: 0;
    font-size: 18px;
    font-weight: 600;
    color: var(--color-text-1);
  }
}

.folder-actions {
  display: flex;
  gap: 12px;
  flex-wrap: wrap;

  > * {
    flex-shrink: 0;
  }
}

.file-list-container {
  border: 1px solid var(--color-border);
  border-radius: 4px;
  padding: 12px;
  margin-top: 16px;
}

.file-list-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 12px;
  padding: 0 8px;
}

.file-table-wrapper {
  max-height: 500px;
  overflow-y: auto;
  border: 1px solid var(--color-border);
  border-radius: 4px;
}

.file-table {
  width: 100%;

  :deep(.arco-table-th) {
    position: sticky;
    top: 0;
    z-index: 1;
    background-color: var(--color-fill-2);
  }
}

.thumbnail-cell {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 60px;

  .thumbnail-image {
    max-height: 60px;
    max-width: 80px;
    object-fit: contain;
    border-radius: 2px;
  }

  .file-icon {
    font-size: 24px;
    color: var(--color-text-3);
  }
}

/* 上传进度框样式 */
.upload-progress-fixed {
  position: fixed;
  bottom: 24px;
  right: 24px;
  width: 360px;
  z-index: 1000;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);
  border-radius: 8px;
  animation: fadeIn 0.3s ease;

  :deep(.arco-card-header) {
    border-bottom: 1px solid var(--color-border);
    padding-bottom: 12px;
  }

  :deep(.arco-progress-text) {
    font-size: 14px;
  }
}

.progress-details {
  margin-top: 12px;
  font-size: 13px;
  color: var(--color-text-2);

  p {
    display: flex;
    align-items: center;
    margin: 6px 0;

    .arco-icon {
      margin-right: 8px;
      font-size: 16px;
    }
  }
}

@keyframes fadeIn {
  from { opacity: 0; transform: translateY(10px); }
  to { opacity: 1; transform: translateY(0); }
}
</style>