<template>
  <div>
    <div class="gva-table-box">
      <div class="gva-btn-list">
        <el-button type="primary" icon="plus" @click="handleAdd('0')">新增广告内容</el-button>
        <el-button icon="delete" style="margin-left: 10px;" :disabled="!multipleSelection.length"
          @click="handleMultiDelete">删除</el-button>
      </div>
      <el-table ref="multipleTable" :data="tableData" row-key="ID" @selection-change="handleSelectionChange">
        <el-table-column fixed type="selection" width="40" align="center" />
        <el-table-column align="left" label="ID" min-width="60" prop="ID" />
        <el-table-column align="left" label="媒体文件" min-width="160" prop="mediaUrl">
          <template #default="scope">
            <el-image v-if="scope.row.adType === 1 || scope.row.adType === 3" :src="scope.row.mediaUrl" class="file"
              fit="cover" :preview-src-list="[scope.row.mediaUrl]" preview-teleported hide-on-click-modal
              close-on-press-escape style="width: 120px; height: 80px" />
            <div v-else-if="scope.row.adType === 2">
              <video :src="scope.row.mediaUrl" controls="controls" style="width: 120px; height: 80px" />
            </div>
          </template>
        </el-table-column>
        <el-table-column align="left" label="类型" min-width="80" prop="adType">
          <template #default="scope">
            {{ formatAdType(scope.row.adType) }}
          </template>
        </el-table-column>
        <el-table-column align="left" label="位置" min-width="120" prop="adPositionId">
          <template #default="scope">
            {{ formatAdPosition(scope.row.adPositionId) }}
          </template>
        </el-table-column>
        <el-table-column align="left" label="跳转地址" min-width="300" prop="url" />
        <el-table-column align="left" label="有效起始" min-width="140" prop="validStart">
          <template #default="scope">
            {{ formatOnlyDate(scope.row.validStart) }}
          </template>
        </el-table-column>
        <el-table-column align="left" label="有效截止" min-width="140" prop="validEnd">
          <template #default="scope">
            {{ formatOnlyDate(scope.row.validEnd) }}
          </template>
        </el-table-column>
        <el-table-column align="left" fixed="right" label="操作" width="160">
          <template #default="scope">
            <el-button type="primary" link icon="edit" @click="handleEdit(scope.row.ID)">编辑</el-button>
            <el-button type="danger" link icon="delete" @click="handleDelete(scope.row.ID)">删除</el-button>
          </template>
        </el-table-column>
      </el-table>
      <div class="gva-pagination">
        <el-pagination layout="total, sizes, prev, pager, next, jumper" :current-page="page" :page-size="pageSize"
          :page-sizes="[10, 30, 50, 100]" :total="total" @current-change="handleCurrentChange"
          @size-change="handleSizeChange" />
      </div>
    </div>

    <el-drawer v-model="dialogFormVisible" size="600" :show-close="false" :before-close="handleCloseDialog"
      :close-on-click-modal="false" :close-on-press-escape="false">
      <template #header>
        <div class="flex justify-between items-center">
          <span class="text-lg">{{ !isEdit ? '添加' : '修改' }}广告内容</span>
          <div>
            <el-button type="primary" @click="handleFormSubmit">确 定</el-button>
            <el-button @click="handleCloseDialog">取 消</el-button>
          </div>
        </div>
      </template>
      <el-form v-if="dialogFormVisible" ref="editFormRef" label-position="top" label-width="auto" :inline="true"
        :model="editForm" :rules="rules">
        <el-form-item label="类型" prop="adType" style="width: 100%">
          <el-select v-model="editForm.adType" placeholder="请选择" allow-create clearable filterable style="width: 100%"
            @change="handleChangeAdType">
            <el-option v-for="item in adTypeOptions" :key="item.key" :label="item.label" :value="item.key" />
          </el-select>
        </el-form-item>
        <el-form-item label="位置" prop="adPositionId" style="width: 100%">
          <el-select v-model="editForm.adPositionId" placeholder="请选择" allow-create clearable filterable
            style="width: 100%" @change="handleChangePosition">
            <el-option v-for="item in positionOptions" :key="item.ID" :label="item.title" :value="item.ID" />
          </el-select>
        </el-form-item>
        <el-form-item label="跳转地址" prop="url" style="width: 100%">
          <el-input v-model="editForm.url" type="url" rows="3" autocomplete="off" style="width: 100%" />
        </el-form-item>
        <el-form-item label="有效起始日期" prop="validStart" style="width: 100%">
          <el-date-picker v-model="editForm.validStart" :clearable="false" style="width: 100%" :editable="false" />
        </el-form-item>
        <el-form-item label="有效截止日期" prop="validEnd" style="width: 100%">
          <el-date-picker v-model="editForm.validEnd" :clearable="false" :editable="false" style="width: 100%" />
        </el-form-item>
        <el-form-item label="媒体（需要先选择 “类型” 和 “位置”）" prop="mediaUrl" style="width: 100%">
          <el-alert v-if="editForm.adType !== '' && editForm.adPositionId !== ''" type="info" :closable="false"
            style="margin-bottom: 10px;"
            :title="`文件类型为：${uploadInfo.mediaTypeInfo}, 大小不超过${uploadInfo.fileSizeInfo}, 宽*高: ${uploadInfo.mediaWidth}px*${uploadInfo.mediaHeight}px`" />
          <div v-if="editForm.adType !== '' && editForm.adPositionId !== ''" class="flex flex-wrap gap-3">
            <el-upload class="avatar-uploader"
              :action="`${imgUploadPath}/cms/mediaFile/upload?category=ad_content_imgs`" :show-file-list="false"
              :on-success="uploadSuccess" :on-error="uploadFailure" :before-upload="beforeUpload">
              <el-button type="primary" plain icon="upload">上传</el-button>
            </el-upload>
          </div>
          <div class="upload-file-box">
            <el-image
              v-if="editForm.mediaUrl !== '' && (uploadInfo.mediaType === 'pic' || uploadInfo.mediaType === 'gif')"
              :src="editForm.mediaUrl" class="avatar" fit="cover"
              style="width: 100%; max-height: 500px; max-width: 500px;" />
            <div v-else-if="editForm.mediaUrl !== '' && uploadInfo.mediaType === 'video'">
              <video :src="editForm.mediaUrl" controls="controls" :width="uploadInfo.mediaWidth"
                :height="uploadInfo.mediaHeight" style="min-width: 280px; min-height: 200px" />
            </div>
          </div>
        </el-form-item>
      </el-form>
    </el-drawer>
  </div>
</template>

<script setup>
import { reactive, ref } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { formatOnlyDate } from '@/utils/format'
import { isImageMime, isVideoMime, isGifMime, checkImageWHEqual } from '@/utils/image'
import {
  getAdContentList,
  addAdContent,
  updateAdContent,
  deleteAdContent,
  deleteAdContentByIds,
  getAdContentById
} from '@/api/adContent'
import { getAdPositionList } from '@/api/adPosition'
import { isUrl } from '@/utils/validator'

const page = ref(1)
const total = ref(0)
const pageSize = ref(10)
const isDateEndGtStart = (rule, value, callback) => {
  console.log('isDateEndGtStart', editForm.value.validStart, value)
  if (value < editForm.value.validStart) {
    callback(new Error(rule.message))
  } else {
    callback()
  }
}
const rules = reactive({
  adType: [
    { required: true, message: '请选择广告类型', trigger: 'blur' }
  ],
  adPositionId: [
    { required: true, message: '请选择广告位', trigger: 'blur' }
  ],
  url: [
    { required: true, message: '请输入跳转地址', trigger: 'blur' },
    { validator: isUrl, message: '请输入正确的跳转地址', trigger: 'blur' }
  ],
  validStart: [
    { required: true, message: '请选择有效起始日期', trigger: 'blur' }
  ],
  validEnd: [
    { required: true, message: '请选择有效截止日期', trigger: 'blur' },
    { validator: isDateEndGtStart, message: '有效截止日期必须大于起始日期', trigger: 'blur' },
  ],
  mediaUrl: [
    { required: true, message: '请上传媒体信息', trigger: 'blur' }
  ],
})
const adTypeOptions = ref([
  { key: 1, label: '图文', mediaType: 'pic', mediaTypeInfo: 'jpg,png,webp,svg', fileSize: 500, fileSizeInfo: '500K' },
  { key: 2, label: '视频', mediaType: 'video', mediaTypeInfo: 'mp4,webm', fileSize: 5000, fileSizeInfo: '5M' },
  { key: 3, label: '动图', mediaType: 'gif', mediaTypeInfo: 'gif', fileSize: 2000, fileSizeInfo: '2M' },
])
const positionOptions = ref([])

const formatAdType = (value) => {
  const rowLabel = adTypeOptions.value.filter(item => item.key === value)
  return rowLabel && rowLabel[0] && rowLabel[0].label
}

const formatAdPosition = (value) => {
  const rowLabel = positionOptions.value.filter(item => item.ID === value)
  return rowLabel && rowLabel[0] && rowLabel[0].title
}

const getPositionData = async () => {
  positionOptions.value = []
  const res = await getAdPositionList({ page: 1, pageSize: 999 })
  if (res.code === 0) {
    positionOptions.value = res.data.list
  }
}

getPositionData()

// 多选
const multipleSelection = ref([])// 多选数据
const handleSelectionChange = (val) => {
  multipleSelection.value = val
}

const handleMultiDelete = () => {
  ElMessageBox.confirm('确定要删除所选广告吗?', '请确认', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning'
  }).then(async () => {
    const IDs = []
    if (multipleSelection.value.length === 0) {
      ElMessage({
        type: 'warning',
        message: '请选择要删除的数据'
      })
      return
    }
    multipleSelection.value &&
      multipleSelection.value.map(item => {
        IDs.push(item.ID)
      })
    const res = await deleteAdContentByIds({ IDs })
    if (res.code === 0) {
      ElMessage({
        type: 'success',
        message: '删除成功'
      })
      if (tableData.value.length === IDs.length && page.value > 1) {
        page.value--
      }
      getTableData()
    }
  })
}

// 查询
const tableData = ref([])
const getTableData = async () => {
  const res = await getAdContentList({ page: page.value, pageSize: pageSize.value })
  if (res.code === 0) {
    tableData.value = res.data.list
  }
}

getTableData()

// 分页
const handleSizeChange = (val) => {
  pageSize.value = val
  getTableData()
}

// 修改页面容量
const handleCurrentChange = (val) => {
  page.value = val
  getTableData()
}

// ----- 以下为 form 操作 -----
const uploadInfo = ref({
  mediaType: '',
  mediaTypeInfo: '',
  fileSize: 0,
  fileSizeInfo: '',
  mediaWidth: 0,
  mediaHeight: 0,
})
const editFormRef = ref(null)
// 提交表单
const handleFormSubmit = async () => {
  editFormRef.value.validate(async valid => {
    if (!valid) {
      return
    }
    let res
    if (isEdit.value) {
      res = await updateAdContent(editForm.value)
    } else {
      res = await addAdContent(editForm.value)
    }
    if (res.code === 0) {
      ElMessage({
        type: 'success',
        message: isEdit.value ? '编辑成功' : '添加成功!'
      })
      getTableData()
      initForm()
      dialogFormVisible.value = false
    }
  })
}

// 初始化弹窗内表格方法
const editForm = ref({})
const checkFlag = ref(false)
const initForm = () => {
  checkFlag.value = false
  editForm.value = {
    ID: 0,
    adType: '',
    adPositionId: '',
    url: '',
    validStart: '',
    validEnd: '',
    mediaUrl: '',
  }
}

// 关闭弹窗
const dialogFormVisible = ref(false)
const handleCloseDialog = () => {
  initForm()
  dialogFormVisible.value = false
}

// 删除
const handleDelete = (ID) => {
  ElMessageBox.confirm('此操作将永久删除广告内容, 是否继续?', '提示', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning'
  })
    .then(async () => {
      const res = await deleteAdContent({ ID })
      if (res.code === 0) {
        ElMessage({
          type: 'success',
          message: '删除成功!'
        })
        if (tableData.value.length === 1 && page.value > 1) {
          page.value--
        }
        getTableData()
      }
    })
    .catch(() => {
      ElMessage({
        type: 'info',
        message: '已取消删除'
      })
    })
}

const handleChangePosition = (value) => {
  if (value === '') {
    return
  }
  const posItems = positionOptions.value.filter(item => item.ID === Number(value))
  if (posItems && posItems.length === 0) {
    return
  }
  uploadInfo.value.mediaWidth = posItems[0].mediaWidth
  uploadInfo.value.mediaHeight = posItems[0].mediaHeight
}
const handleChangeAdType = (value) => {
  if (!value) {
    return
  }
  const typeItems = adTypeOptions.value.filter(item => item.key === Number(value))
  if (typeItems && typeItems.length === 0) {
    return
  }
  uploadInfo.value.mediaType = typeItems[0].mediaType
  uploadInfo.value.mediaTypeInfo = typeItems[0].mediaTypeInfo
  uploadInfo.value.fileSize = typeItems[0].fileSize
  uploadInfo.value.fileSizeInfo = typeItems[0].fileSizeInfo
}

const isEdit = ref(false)
const dialogTitle = ref('新增广告内容')
const handleAdd = (id) => {
  dialogTitle.value = '新增广告内容'
  initForm()
  isEdit.value = false
  dialogFormVisible.value = true
}
// 修改方法
const handleEdit = async (ID) => {
  dialogTitle.value = '编辑广告内容'
  const res = await getAdContentById({ ID })
  editForm.value = res.data.adContent
  handleChangePosition(editForm.value.adPositionId)
  handleChangeAdType(editForm.value.adType)
  isEdit.value = true
  dialogFormVisible.value = true
}

// ----- 以下为图片操作 -----
const imgUploadPath = ref(import.meta.env.VITE_BASE_API)
const beforeUpload = (file) => {
  const isLtSize = file.size / 1024 < uploadInfo.value.fileSize
  const isVideo = isVideoMime(file.type)
  const isImage = isImageMime(file.type)
  const isGif = isGifMime(file.type)

  if (uploadInfo.value.mediaType === 'pic' && !isImage) {
    ElMessage.error('上传文件只能是 ' + uploadInfo.value.mediaTypeInfo + ' 格式')
    return false
  }
  if (uploadInfo.value.mediaType === 'video' && !isVideo) {
    ElMessage.error('上传文件只能是 ' + uploadInfo.value.mediaTypeInfo + ' 格式')
    return false
  }
  if (uploadInfo.value.mediaType === 'gif' && !isGif) {
    ElMessage.error('上传文件只能是 ' + uploadInfo.value.mediaTypeInfo + ' 格式')
    return false
  }
  if (!isLtSize) {
    ElMessage.error('上传文件大小不能超过 ' + uploadInfo.value.fileSizeInfo)
    return false
  }

  if (uploadInfo.value.mediaType === 'pic') {
    const isSize = checkImageWHEqual(
      file, uploadInfo.value.mediaWidth, uploadInfo.value.mediaHeight
    ).then(
      () => {
        return file
      },
      () => {
        ElMessage.error('上传文件宽*高必须为: ' + uploadInfo.value.mediaWidth + 'px*' + uploadInfo.value.mediaHeight + 'px')
        return Promise.reject()
      })
    return isSize
  }

  return true
}

const uploadSuccess = (res) => {
  const { code, data, msg } = res
  if (code !== 0) {
    ElMessage({ type: 'error', message: msg })
    return
  }
  if (!data.mediaFile) {
    ElMessage({ type: 'error', message: '返回错误，上传失败' })
    return
  }
  editForm.value.mediaUrl = data.mediaFile.url
}

const uploadFailure = () => {
  ElMessage({
    type: 'error',
    message: '上传失败'
  })
}

</script>

<style>
.upload-file-box {
  display: block;
  width: 100%;
}
</style>

<style scoped>
.avatar-uploader .avatar {
  width: 100%;
  height: 100%;
  display: block;
}
</style>

<style>
.avatar-uploader .el-upload {
  border: 1px solid var(--el-border-color);
  border-radius: 6px;
  cursor: pointer;
  position: relative;
  overflow: hidden;
  transition: var(--el-transition-duration-fast);
}

.avatar-uploader .el-upload:hover {
  border-color: var(--el-color-primary);
}

.el-icon.avatar-uploader-icon {
  font-size: 28px;
  color: #8c939d;
  width: 178px;
  height: 178px;
  text-align: center;
}

.admin-box .el-table td .cell {
  line-height: 28px;
}
</style>
