<template>
<div class="page-wrapper">
  <el-alert type="info" show-icon :closable="false" >
    <template #title>上传要求</template>
    图片格式为{{allowUploadExt.join('、')}}，文件大小不超过10MB。
  </el-alert>
  <div class="btn-container" style="margin-top:10px;">
    <el-upload
      action="/api/source-image/upload"
      accept="image/jpeg,image/png,image/svg+xml,image/x-icon"
      name="image"
      :headers="{token: store.state.loginInfo.token}"
      :before-upload="beforeUpload"
      :on-success="uploadSuccess"
      :on-error="uploadError" 
      auto-upload
      :show-file-list="false"
      style="display: inline-block;margin-right: 10px;">
      <el-button type="primary" icon="Upload" :loading="isUploading">上传图片</el-button>
    </el-upload>
    <el-button type="danger" @click="deleteAll" style="vertical-align: bottom">批量删除</el-button>
  </div>
  <div class="table-container">
    <el-table :data="sourceImageData" v-loading="loading" stripe @selection-change="dataSelect">
      <el-table-column type="selection" width="55" />
      <el-table-column prop="hash" label="md5" width="300" />
      <el-table-column prop="size" label="文件大小" >
        <template #default="scope">
          {{ prettyBytes(scope.row.size) }}
        </template>
      </el-table-column>
      <el-table-column prop="mime" label="MIME" />
      <el-table-column prop="label" label="标签" >
        <template #default="scope">
          <el-tag v-for="label in scope.row.label" :key="label" effect="plain">{{label}}</el-tag>
        </template>
      </el-table-column>
      <el-table-column prop="createdAt" label="上传时间" >
        <template #default="scope">
          {{ datetimeFormat(scope.row.createdAt) }}
        </template>
      </el-table-column>
      <el-table-column label="操作" >
        <template #default="scope">
          <el-button link icon="EditPen" type="primary" plain @click="modifyTags(scope.row)" title="修改标签"></el-button>
          <el-button link icon="View" plain @click="preview(scope.row)" title="预览"></el-button>
        </template>
      </el-table-column>
    </el-table>
  </div>
  <div class="page-container">
    <el-pagination background 
      :page-sizes="store.state.pageSizeOpts"
      :layout="store.state.pageLayout"
      :current-page="search.pageNum"
      :total="total"
      @size-change="pageSizeChange"
      @current-change="pageChange">
    </el-pagination>
  </div>
  <el-dialog v-model="modifyModal" title="修改标签" width="630px" @closed="loadData">
    <el-transfer
      v-model="curModifyLabels"
      filterable
      :render-content="renderFunc"
      :titles="['可选标签', '已选标签']"
      :format="{
        noChecked: '${total}',
        hasChecked: '${checked}/${total}',
      }"
      @change="tarnsferChange"
      :data="labels"
    ></el-transfer>
  </el-dialog>
</div>
</template>
<script setup lang="ts">
import { ref, computed, h } from 'vue'
import { useStore } from 'vuex'
import { ElMessage, ElMessageBox } from 'element-plus'
import prettyBytes from 'pretty-bytes'
import { MsgResult, Page } from '@/model/common.dto'
import { useBaseList } from '@/model/baselist'
import { SourceImageModel } from '@/model/api/source-image'
import http from '@/utils/http'

const store = useStore()
const { loading, total, search, setLoadData, pageChange, pageSizeChange, datetimeFormat } = useBaseList(new Page())

const allowUploadExt = ['jpg', 'jpeg', 'png', 'svg', 'ico']
const sourceImageData = ref<SourceImageModel[]>([])
const curModifyLabels = ref<string[]>([])
const labelList = ref<string[]>([])
const curId = ref<string | null>(null)
const modifyModal = ref(false)
const isUploading = ref(false)

function renderFunc(h: Function, option: any) {
  return h('span', null, option.label)
}
const labels = computed(() => {
  return labelList.value.map(item => {
    return { key: item, label: item }
  })
})

let selectedData: string[] = []

async function loadData(): Promise<void> {
  loading.value = true
  const data = await http.get<Page, any>('/api/v2/source-image/list', {params: search})
  selectedData = []
  loading.value = false
  total.value = data.total
  sourceImageData.value = data.list
}
setLoadData(loadData)

function deleteAll(): void {
  if (!selectedData.length) {
    ElMessage.warning('请选择要删除的数据')
    return
  }
  ElMessageBox.confirm(`是否确认删除选中的${selectedData.length}条数据？`, '确认删除', {type: 'warning'}).then(async () => {
    await http.delete('/api/v2/source-image/delete', {params: {_ids: selectedData}})
    ElMessage.success('删除成功')
    loadData()
  }).catch(() => {})
}
function dataSelect(selection: SourceImageModel[]): void {
  selectedData = selection.map(item => item._id)
}
function beforeUpload(file: File): boolean {
  if (file.size > 10 << 20) {
    ElMessage.warning('文件大小超过10MB')
    return false
  }
  isUploading.value = true
  return true
}
function uploadSuccess(response: MsgResult): void {
  if (response.code === 0) {
    ElMessage.success(response.message)
    loadData()
  } else {
    ElMessage.warning(response.message)
  }
  isUploading.value = false
}
function uploadError(error: Error): void {
  isUploading.value = false
  ElMessage.error(error.message)
}
function preview(row: SourceImageModel): void {
  ElMessageBox({
    title: '图片预览',
    message: h('img', { style: `width:500px`, src: `/api/v2/common/randomBg?id=${row._id}` }, ''),
    showCancelButton: false,
    confirmButtonText: '关闭',
    customStyle: {width: '530px', maxWidth: 'unset'}
  }).catch(() => {})
}
function modifyTags(item: SourceImageModel): void {
  curModifyLabels.value.length = 0
  if (item.label) {
    curModifyLabels.value.push(...item.label)
  }
  curId.value = item._id
  modifyModal.value = true
}
async function tarnsferChange(newTargetKeys: string[], direction: 'right' | 'left', moveKeys: string[]) {
  await http.post('/api/v2/source-image/updateLabel', {id: curId.value, labels: newTargetKeys})
}

// created
http.get<never, any>('/api/v2/common/config/image_label').then(data => {
  labelList.value.push(...data)
  loadData()
})
</script>