<template>
  <div>
    <selectComponent :rounded="rounded" v-if="!props.multiple" :model="model" @chooseItem="openChooseImg" @deleteItem="openChooseImg" />
    <div v-else class="w-full gap-4 flex flex-wrap">
      <selectComponent :rounded="rounded" v-for="(item, index) in model" :key="index" :model="item" @chooseItem="openChooseImg"
                       @deleteItem="deleteImg(index)"
      />
      <selectComponent :rounded="rounded" v-if="model.length < props.maxUpdateCount || props.maxUpdateCount === 0"
                       @chooseItem="openChooseImg" @deleteItem="openChooseImg"
      />
    </div>

    <el-drawer v-model="drawer" title="媒体库 | 点击“文件名”可以编辑，选择的类别即是上传的类别" :size="880">
      <div class="flex">
        <div class="w-64" style="border-right: solid 1px var(--el-border-color);">
          <el-scrollbar style="height: calc(100vh - 110px)">
            <el-tree
                :data="categories"
                node-key="id"
                :props="defaultProps"
                @node-click="handleNodeClick"
                default-expand-all
            >
              <template #default="{ node, data }">
                <div class="w-36" :class="search.classId === data.ID ? 'text-blue-500 font-bold' : ''">{{ data.name }}
                </div>
                <el-dropdown>
                  <el-icon class="ml-3 text-right" v-if="data.ID > 0"><MoreFilled /></el-icon>
                  <el-icon class="ml-3 text-right mt-1" v-else><Plus /></el-icon>
                  <template #dropdown>
                    <el-dropdown-menu>
                      <el-dropdown-item @click="addCategoryFun(data)">添加分类</el-dropdown-item>
                      <el-dropdown-item @click="editCategory(data)" v-if="data.ID > 0">编辑分类</el-dropdown-item>
                      <el-dropdown-item @click="deleteCategoryFun(data.ID)" v-if="data.ID > 0">删除分类</el-dropdown-item>
                    </el-dropdown-menu>
                  </template>
                </el-dropdown>
              </template>
            </el-tree>
          </el-scrollbar>
        </div>
        <div class="ml-4 w-[605px]">
          <div class="gva-btn-list gap-2">
            <el-input v-model.trim="search.keyword" class="w-96" placeholder="请输入文件名或备注" clearable />
            <el-button type="primary" icon="search" @click="onSubmit"></el-button>
          </div>
          <div class="gva-btn-list gap-2">
            <el-button @click="useSelectedImages" type="danger" :disabled="selectedImages.length === 0" :icon="ArrowLeftBold">选定</el-button>
            <upload-common :image-common="imageCommon" :classId="search.classId" @on-success="onSuccess" />
            <cropper-image :classId="search.classId" @on-success="onSuccess" />
            <QRCodeUpload :classId="search.classId" @on-success="onSuccess" />
            <upload-image :image-url="imageUrl" :file-size="2048" :max-w-h="1080" :classId="search.classId" @on-success="onSuccess" />
          </div>
          <div class="flex flex-wrap gap-4">
            <div v-for="(item,key) in picList" :key="key" class="w-40">
              <div class="w-40 h-40 border rounded overflow-hidden border-dashed border-gray-300 cursor-pointer relative group">
                <el-image :key="key" :src="getUrl(item.url)" fit="cover" class="w-full h-full relative" @click="toggleImageSelection(item)" :class="{ selected: isSelected(item) }">
                  <template #error>
                    <el-icon v-if="isVideoExt(item.url || '')" :size="32" class="absolute top-[calc(50%-16px)] left-[calc(50%-16px)]">
                      <VideoPlay />
                    </el-icon>
                    <video v-if="isVideoExt(item.url || '')"
                           class="w-full h-full object-cover"
                           muted
                           preload="metadata"
                           @click="toggleImageSelection(item)"
                           :class="{ selected: isSelected(item) }"
                    >
                      <source :src="getUrl(item.url) + '#t=1'">
                      您的浏览器不支持视频播放
                    </video>
                    <div v-else class="w-full h-full object-cover flex items-center justify-center">
                      <el-icon :size="32">
                        <icon-picture />
                      </el-icon>
                    </div>
                  </template>
                </el-image>
                <div class="absolute -right-1 top-1 w-8 h-8 group-hover:inline-block hidden" @click="deleteCheck(item)">
                  <el-icon :size="18">
                    <CloseBold />
                  </el-icon>
                </div>
              </div>
              <div class="overflow-hidden text-nowrap overflow-ellipsis text-center w-full cursor-pointer" @click="editFileNameFunc(item)">
                {{ item.name }}
              </div>
            </div>
          </div>
          <el-pagination
              :current-page="page"
              :page-size="pageSize"
              :total="total"
              class="justify-center"
              layout="total, prev, pager, next, jumper"
              @current-change="handleCurrentChange"
              @size-change="handleSizeChange"
          />
        </div>
      </div>
    </el-drawer>


    <!-- 添加分类弹窗 -->
    <el-dialog v-model="categoryDialogVisible" @close="closeAddCategoryDialog" width="520"
               :title="(categoryFormData.ID === 0 ? '添加' : '编辑') + '分类'"
               draggable
    >
      <el-form ref="categoryForm" :rules="rules" :model="categoryFormData" label-width="80px">
        <el-form-item label="上级分类">
          <el-tree-select
              v-model="categoryFormData.pid"
              :data="categories"
              check-strictly
              :props="defaultProps"
              :render-after-expand="false"
              style="width: 240px"
          />
        </el-form-item>
        <el-form-item label="分类名称" prop="name">
          <el-input v-model.trim="categoryFormData.name" placeholder="分类名称"></el-input>
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="closeAddCategoryDialog">取消</el-button>
        <el-button type="primary" @click="confirmAddCategory">确定</el-button>
      </template>
    </el-dialog>
  </div>
</template>

<script setup>
import { getUrl, isVideoExt } from '@/utils/image'
import { ref } from 'vue'
import { getFileList, editFileName, deleteFile } from '@/api/fileUploadAndDownload'
import UploadImage from '@/components/upload/image.vue'
import UploadCommon from '@/components/upload/common.vue'
import WarningBar from '@/components/warningBar/warningBar.vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import {
  ArrowLeftBold,
  CloseBold,
  MoreFilled,
  Picture as IconPicture,
  Plus,
  VideoPlay
} from '@element-plus/icons-vue'
import selectComponent from '@/components/selectImage/selectComponent.vue'
import { addCategory, deleteCategory, getCategoryList } from '@/api/attachmentCategory'
import CropperImage from "@/components/upload/cropper.vue";
import QRCodeUpload from "@/components/upload/QR-code.vue";

const imageUrl = ref('')
const imageCommon = ref('')

const search = ref({
  keyword: null,
  classId: 0
})
const page = ref(1)
const total = ref(0)
const pageSize = ref(20)

const model = defineModel({ type: [String, Array] })

const props = defineProps({
  multiple: {
    type: Boolean,
    default: false
  },
  fileType: {
    type: String,
    default: ''
  },
  maxUpdateCount: {
    type: Number,
    default: 0
  },
  rounded: {
    type: Boolean,
    default: false
  }
})

const deleteImg = (index) => {
  model.value.splice(index, 1)
}

const handleSizeChange = (val) => {
  pageSize.value = val
  getImageList()
}

const handleCurrentChange = (val) => {
  page.value = val
  getImageList()
}

const onSubmit = () => {
  search.value.classId = 0
  page.value = 1
  getImageList()
}

const editFileNameFunc = async(row) => {
  ElMessageBox.prompt('请输入文件名或者备注', '编辑', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    inputPattern: /\S/,
    inputErrorMessage: '不能为空',
    inputValue: row.name
  }).then(async({ value }) => {
    row.name = value
    const res = await editFileName(row)
    if (res.code === 0) {
      ElMessage({
        type: 'success',
        message: '编辑成功!'
      })
      await getImageList()
    }
  }).catch(() => {
    ElMessage({
      type: 'info',
      message: '取消修改'
    })
  })
}

const drawer = ref(false)
const picList = ref([])

const imageTypeList = ['png', 'jpg', 'jpeg', 'gif', 'bmp', 'webp', 'svg']
const videoTypeList = ['mp4', 'avi', 'rmvb', 'rm', 'asf', 'divx', 'mpg', 'mpeg', 'mpe', 'wmv', 'mkv', 'vob']

const listObj = {
  image: imageTypeList,
  video: videoTypeList
}

const chooseImg = (url) => {
  if (props.fileType) {
    const typeSuccess = listObj[props.fileType].some(item => {
      if (url?.toLowerCase().includes(item)) {
        return true
      }
    })
    if (!typeSuccess) {
      ElMessage({
        type: 'error',
        message: '当前类型不支持使用'
      })
      return
    }
  }
  //if (props.multiple) {
  //  model.value.push(url)
  //} else {
  model.value = url
  //}
  drawer.value = false
}

const openChooseImg = async() => {
  if (model.value && !props.multiple) {
    model.value = ''
    return
  }
  await getImageList()
  await fetchCategories()
  drawer.value = true
}

const getImageList = async() => {
  const res = await getFileList({ page: page.value, pageSize: pageSize.value, ...search.value })
  if (res.code === 0) {
    picList.value = res.data.list
    total.value = res.data.total
    page.value = res.data.page
    pageSize.value = res.data.pageSize
  }
}

const deleteCheck = (item) => {
  ElMessageBox.confirm('是否删除该文件', '提示', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning'
  }).then(async() => {
    const res = await deleteFile(item)
    if (res.code === 0) {
      ElMessage({
        type: 'success',
        message: '删除成功!'
      })
      await getImageList()
    }
  }).catch(() => {
    ElMessage({
      type: 'info',
      message: '已取消删除'
    })
  })
}

const defaultProps = {
  children: 'children',
  label: 'name',
  value: 'ID'
}

const categories = ref([])
const fetchCategories = async() => {
  const res = await getCategoryList()
  let data = {
    name: '全部分类',
    ID: 0,
    pid: 0,
    children:[]
  }
  if (res.code === 0) {
    categories.value = res.data || []
    categories.value.unshift(data)
  }
}

const handleNodeClick = (node) => {
  search.value.keyword = null
  search.value.classId = node.ID
  page.value = 1
  getImageList()
}

const onSuccess = () => {
  search.value.keyword = null
  page.value = 1
  getImageList()
}

const categoryDialogVisible = ref(false)
const categoryFormData = ref({
  ID: 0,
  pid: 0,
  name: ''
})

const categoryForm = ref(null)
const rules = ref({
  name: [
    { required: true, message: '请输入分类名称', trigger: 'blur' },
    { max: 20, message: '最多20位字符', trigger: 'blur' }
  ]
})

const addCategoryFun = (category) => {
  categoryDialogVisible.value = true
  categoryFormData.value.ID = 0
  categoryFormData.value.pid = category.ID
}

const editCategory = (category) => {
  categoryFormData.value = {
    ID: category.ID,
    pid: category.pid,
    name: category.name
  }
  categoryDialogVisible.value = true
}

const deleteCategoryFun = async(id) => {
  const res = await deleteCategory({ id: id })
  if (res.code === 0) {
    ElMessage.success({ type: 'success', message: '删除成功' })
    await fetchCategories()
  }
}

const confirmAddCategory = async() => {
  categoryForm.value.validate(async valid => {
    if (valid) {
      const res = await addCategory(categoryFormData.value)
      if (res.code === 0) {
        ElMessage({ type: 'success', message: '操作成功' })
        await fetchCategories()
        closeAddCategoryDialog()
      }
    }
  })
}

const closeAddCategoryDialog = () => {
  categoryDialogVisible.value = false
  categoryFormData.value = {
    ID: 0,
    pid: 0,
    name: ''
  }
}

const selectedImages = ref([])

const toggleImageSelection = (item) => {
  if (props.multiple === false) {
    chooseImg(item.url)
    return
  }
  const index = selectedImages.value.findIndex(img => img.ID === item.ID)
  if (index > -1) {
    selectedImages.value.splice(index, 1)
  } else {
    selectedImages.value.push(item)
  }
}

const isSelected = (item) => {
  return selectedImages.value.some(img => img.ID === item.ID)
}

const useSelectedImages = () => {
  selectedImages.value.forEach((item) => {
    model.value.push(item.url)
  })
  drawer.value = false
  selectedImages.value = []
}

</script>
<style scoped>
.selected {
  border: 3px solid #409eff;
}

.selected:before {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  border: 10px solid #409eff;
}

.selected:after {
  content: "";
  width: 9px;
  height: 14px;
  position: absolute;
  left: 6px;
  top: 0;
  border: 3px solid #fff;
  border-top-color: transparent;
  border-left-color: transparent;
  transform: rotate(45deg);
}
</style>
