<template>
  <div>
    <search-module :search="search" :table="table">
      <template #btn>
        <el-button @click="onAddFolder" type="success">新增文件夹</el-button>
        <el-button @click="onAddFiles" type="success">添加文件</el-button>
        <el-button @click="onMove" type="warning">移动</el-button>
      </template>
    </search-module>
    <div id="table-drag-wrap">
      <table-module :table="table" @selection-change="onChangeSelection">
        <template #headerBtn>
          <div class="flex items-center">
            <p v-for="(item, i) in parentPaths" :key="item.value">
              <button
                :class="[
                  'text-[13px] text-[#09aaff] mx-1',
                  { '!text-[#666] cursor-default': i === parentPaths.length - 1 }
                ]"
                @click="onGoParentFile(item.value)"
              >
                {{ item.label }}
              </button>
              <span :class="['text-xs text-[#666]', { hidden: i === parentPaths.length - 1 }]"
                >></span
              >
            </p>
          </div>
        </template>
        <template #fileName="scope">
          <div>
            <div v-if="curRenameId !== scope.row.id" class="flex items-center">
              <p>
                <el-icon class="mt-1" v-if="scope.row.type === 'file'"><Files /></el-icon>
                <img
                  class="w-4 h-4"
                  v-else-if="scope.row.type === 'image'"
                  :src="scope.row.resourceUrl"
                  alt=""
                />
                <video
                  class="w-4 h-4"
                  v-else-if="scope.row.type === 'video'"
                  :src="scope.row.resourceUrl"
                  alt=""
                />
              </p>
              <span class="ml-2 cursor-pointer" @click="onGoFolder(scope.row)">{{
                scope.row.fileName
              }}</span>
            </div>
            <el-input
              ref="inputRef"
              v-else
              v-model="renameInputVal"
              size="small"
              class="w-40"
              @keyup.enter="handleInputConfirm(scope.row)"
              @blur="handleInputCancel(scope.row)"
            />
          </div>
        </template>
      </table-module>
    </div>
    <dialog-module :dialog="$dialog">
      <template #parentId>
        <el-tree-select
          show-checkbox
          v-model="$dialog.data.parentId"
          :data="treeData"
          :render-after-expand="false"
          check-strictly
          :load="handleLoadNode"
          lazy
          style="width: 240px"
        >
        </el-tree-select>
      </template>
      <template #files>
        <el-upload
          multiple
          :auto-upload="false"
          v-model:file-list="fileList"
          list-type="picture-card"
          :on-preview="handlePictureCardPreview"
          :on-remove="handleRemove"
        >
          <el-icon><Plus /></el-icon>
        </el-upload>
      </template>
    </dialog-module>
    <el-dialog v-model="showReviewImgDialog">
      <img w-full :src="reviewImageUrl" alt="Preview Image" />
    </el-dialog>
  </div>
</template>

<script lang="ts" setup>
import { useDraggable } from 'vue-draggable-plus'
import { initConfig } from './config'
import { ElMessage } from 'element-plus'
import type { UploadProps } from 'element-plus'
import { Plus, Files } from '@element-plus/icons-vue'

const dialogType = ref('')

// 增加文件
const treeData = ref<any[]>([])
const onAddFiles = async () => {
  const dialog = $dialog.value
  dialog.title = '新增'
  dialog.show = true
  $dialog.value.config.files.show = true
  dialogType.value = 'add'
  dialog.data = {}
}

// 加载子文件夹
const handleLoadNode = (node, resolve) => {
  api.resource.getResourceList.post!<any>({ parentId: node.data.value || 0 }).then((res) => {
    resolve(
      res.data.rows
        .filter((item) => item.type === 'file')
        .map((item) => ({ label: item.fileName, value: item.id }))
    )
  })
}
const addFileType = ref('')
// 添加文件夹
const onAddFolder = () => {
  curRenameId.value = Infinity
  renameInputVal.value = ''
  addFileType.value = 'folder'
  table.value.$data.push({
    id: Infinity,
    parentId: search.value.$data.parentId,
    defaultSort: 0,
    type: 'file',
    fileName: ''
  })
}

// 删除
const onDelete = (row: any) => {
  handleMessageBox({
    msg: `是否确认删除吗?`,
    success: api.resource.deleteResource.post!,
    data: { resourceIds: [row.id] }
  }).then(() => {
    table.value.$onGetData(table.value)
  })
}

// 跳转
const onJump = (row: any) => {
  search.value.$data.parentId = row.locations[row.locations.length - 1].id
  table.value.$onGetData(table.value, 1, search)
}

// 移动
const onMove = () => {
  if (!selectFiles.value.length) {
    return ElMessage.error('请先选择文件')
  }
  dialogType.value = 'move'
  $dialog.value.config.files.show = false
  $dialog.value.data = {}
  $dialog.value.show = true
}

const parentPaths = ref([{ label: '全部文件', value: 0 }])

// 去上一页
const onGoParentFile = (id: number) => {
  parentPaths.value = parentPaths.value.slice(
    0,
    parentPaths.value.findIndex((item) => item.value === id) + 1
  )
  search.value.$data.parentId = id
  table.value.$onGetData(table.value, 1, search)
}

// 重命名
const curRenameId = ref(NaN)
const renameInputVal = ref('')
const onRename = (row: any) => {
  renameInputVal.value = row.fileName
  curRenameId.value = row.id
  addFileType.value = ''
}

// 回车确认
const handleInputConfirm = async (row: any) => {
  if (addFileType.value === 'folder') {
    delete row.id
  }
  await api.resource.addOrEditResource.post!([{ ...row, fileName: renameInputVal.value }])
  ElMessage.success('操作成功')
  row.fileName = renameInputVal.value
  curRenameId.value = NaN
}

// 失焦
const handleInputCancel = (row: any) => {
  curRenameId.value = row.fileName
  addFileType.value = ''
}

// 跳子文件夹
const onGoFolder = (row: any) => {
  search.value.$data.parentId = row.id
  parentPaths.value.push({ label: row.fileName, value: row.id })
  table.value.$onGetData(table.value, 1, search)
}

const selectFiles = ref([])
// 勾选文件
const onChangeSelection = (data: any) => {
  selectFiles.value = data
}

const fileList = ref([])
const showReviewImgDialog = ref(false)
const reviewImageUrl = ref('')
const handleRemove: UploadProps['onRemove'] = (uploadFile, uploadFiles) => {
  console.log(uploadFile, uploadFiles)
}

const handlePictureCardPreview: UploadProps['onPreview'] = (uploadFile) => {
  reviewImageUrl.value = uploadFile.url!
  showReviewImgDialog.value = true
}

// 拖拽完成处理
const handleDragEnd = async (evt: any) => {
  const { oldIndex, newIndex } = evt
  // 检查是否真的发生了位置变化
  if (oldIndex === newIndex) {
    console.log('位置没有变化，无需更新')
    return
  }
  try {
    await api.resource.sortResource.post!({ resourceIds: table.value.$data.map((item) => item.id) })
    ElMessage.success('排序更新成功')
    // 可选：刷新数据
    // table.value.$onGetData(table.value, 1, search)
  } catch (error) {
    ElMessage.error('排序更新失败')
  }
}

/** 初始化页面 */
const ConfigData = initConfig()
const { search, table, $dialog } = handleInit(ConfigData, api.resource.getResourceList.post, [
  onRename,
  onDelete,
  onJump
])
search.value.$default = { parentId: 0 }
table.value.$onGetData(table.value, 1, search)
$dialog.value['item-width'] = '100%'
$dialog.value.submit = async () => {
  if (dialogType.value === 'add') {
    const form = new FormData()
    // 关键：一次性把所有文件塞到同一个键 'files'
    fileList.value.forEach((f) => {
      form.append('files', f.raw as File)
    })
    const res = await api.resource.uploadFile.post!<any>(form)
    const params = res.data.map((item) => ({
      fileName: item.srcFileName,
      resourceUrl: item.url,
      defaultSort: 0,
      parentId: $dialog.value.data.parentId,
      type: 'image'
    }))
    await api.resource.addOrEditResource.post!(params)
    ElMessage.success('操作成功')
    $dialog.value.show = false
  } else {
    const params = selectFiles.value.map((item: any) => ({
      ...item,
      parentId: $dialog.value.data.parentId
    }))
    await api.resource.addOrEditResource.post!(params)
    ElMessage.success('操作成功')
    $dialog.value.show = false
    table.value.$onGetData(table.value, 1, search)
    selectFiles.value = []
  }
}
// table.value.$data = originData

// 拖拽实例
let draggableInstance: any = null

// 初始化拖拽功能
const initDraggable = () => {
  setTimeout(() => {
    const tbody = document.querySelector('#table-drag-wrap .el-table__body tbody')
    if (tbody && table.value.$data.length > 0) {
      // 如果已有实例，先销毁
      if (draggableInstance) {
        draggableInstance.destroy?.()
      }

      // 创建新的拖拽实例
      draggableInstance = useDraggable(tbody, table.value.$data, {
        onEnd: (evt) => {
          handleDragEnd(evt)
        }
      })
    }
  }, 100)
}

// 监听表格数据变化，自动重新初始化拖拽
watch(
  () => table.value.$data,
  (val) => {
    initDraggable()
  },
  { deep: true }
)

/** 页面缓存 */
defineOptions({ name: 'ResourceList' })
</script>
