<template>
  <div>
    <div class="gva-search-box">
      <el-form ref="elSearchFormRef" :inline="true" :model="searchInfo" label-width="90px" class="demo-form-inline"
        @keyup.enter="handleSubmitSearch">
        <el-form-item label="关键词" style="width:300px">
          <template #label>
            <span>
              <el-tooltip content="从标题和简介中搜索" placement="top-start">
                <el-icon>
                  <QuestionFilled />
                </el-icon>
              </el-tooltip>
              关键词
            </span>
          </template>
          <el-input v-model="searchInfo.keyword" class="keyword" placeholder="请输入" clearable style="width:100%" />
        </el-form-item>
        <el-form-item>
          <el-button type="primary" icon="search" @click="handleSubmitSearch">查询</el-button>
          <el-button icon="refresh" @click="handleResetSearch">重置</el-button>
        </el-form-item>
      </el-form>
    </div>
    <div class="gva-table-box">
      <div class="gva-btn-list">
        <el-button type="primary" icon="plus" @click="handleAdd('0')">新增直播</el-button>
      </div>
      <el-table :data="tableData" row-key="ID">
        <el-table-column type="expand">
          <template #default="scope">
            <div>
              <div class="gva-table-expand" style="max-width: 600px;">
                <el-text tag="b">简介</el-text>
              </div>
              <div class="gva-table-expand" style="max-width: 600px;">
                {{ scope.row.brief }}
              </div>
              <div class="gva-table-expand" style="max-width: 600px;">
                <el-text tag="b">时间线</el-text>
              </div>
              <div class="gva-table-expand" style="max-width: 600px;">
                <el-timeline style="max-width: 600px;">
                  <el-timeline-item v-for="(item, index) in JSON.parse(scope.row.liveTimeline)" :key="index"
                    hide-timestamp>
                    <div>
                      <div>{{ item.title }}</div>
                      <el-text size="small">{{ item.content }}</el-text>
                    </div>
                  </el-timeline-item>
                </el-timeline>
              </div>
            </div>
          </template>
        </el-table-column>
        <el-table-column align="left" label="ID" min-width="50" prop="ID" />
        <el-table-column align="left" label="封面" min-width="180" prop="cover">
          <template #default="scope">
            <el-image :src="scope.row.cover" class="gva-image" fit="contain" :preview-src-list="[scope.row.cover]"
              preview-teleported hide-on-click-modal close-on-press-escape style="width: 160px; height: 90px;" />
          </template>
        </el-table-column>
        <el-table-column align="left" label="标题" min-width="220" prop="title" />
        <el-table-column align="left" label="直播/回放地址" min-width="450" prop="liveUrl">
          <template #default="scope">
            <p>直播：<el-text>{{ scope.row.liveUrl }}</el-text></p>
            <p>回放：<el-text>{{ scope.row.replayUrl }}</el-text></p>
          </template>
        </el-table-column>
        <el-table-column align="left" label="直播时间" min-width="220" prop="liveTime">
          <template #default="scope">
            <p>开始：<el-text>{{ formatDate(scope.row.startTime) }}</el-text></p>
            <p>结束：<el-text>{{ formatDate(scope.row.endTime) }}</el-text></p>
          </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="900" :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" :model="editForm"
        :rules="rules" style="width: 100%">
        <el-row :gutter="15">
          <el-col :span="16">
            <el-form-item label="标题" prop="title" style="width: 100%">
              <el-input v-model="editForm.title" autocomplete="off" />
            </el-form-item>
            <el-form-item label="简介" prop="brief" style="width: 100%">
              <el-input type="textarea" rows="4" v-model="editForm.brief" autocomplete="off" />
            </el-form-item>
            <el-form-item label="直播地址" prop="liveUrl" style="width: 100%">
              <el-input v-model="editForm.liveUrl" autocomplete="off" placeholder="url地址" />
            </el-form-item>
            <el-form-item label="回放地址" prop="replayUrl" style="width: 100%">
              <el-input v-model="editForm.replayUrl" autocomplete="off" placeholder="url地址" />
            </el-form-item>
            <el-form-item label="时间线" prop="liveTimeline" style="width: 100%">
              <template #default="scope">
                <el-timeline hide-timestamp>
                  <el-timeline-item placement="top" v-for="(item, index) in liveTimelineArr">
                    <el-row :gutter="10" style="width: 100%">
                      <el-col :span="18">
                        <div class="gva-multi-input">
                          <el-input v-model="item.title" style="width: 100%; margin-bottom: 10px;" placeholder="时间线标题"
                            @blur="timelineBlur" />
                          <el-input v-model="item.content" type="textarea" rows="3" style="width: 100%"
                            placeholder="时间线内容" />
                        </div>
                      </el-col>
                      <el-col :span="6">
                        <el-button type="primary" plain size="small" @click="timelineAdd(index)">
                          <el-icon>
                            <Plus />
                          </el-icon>
                        </el-button>
                        <el-button type="danger" plain size="small" v-if="index > 0" @click="timelineDel(index)">
                          <el-icon>
                            <Minus />
                          </el-icon>
                        </el-button>
                      </el-col>
                    </el-row>
                  </el-timeline-item>
                </el-timeline>
              </template>
            </el-form-item>
          </el-col>
          <el-col :span="1"><el-divider direction="vertical" style="height: 100%" /></el-col>
          <el-col :span="7">
            <el-form-item label="封面" prop="cover" style="width: 100%">
              <el-upload class="avatar-uploader" :action="`${imgUploadPath}/cms/mediaFile/upload?category=live_cover`"
                :show-file-list="false" :on-success="uploadSuccess" :on-error="uploadFailure"
                :before-upload="beforeUpload">
                <img v-if="editForm.cover" :src="editForm.cover" class="avatar" style="object-fit: cover;">
                <el-icon v-else class="avatar-uploader-icon">
                  <Plus />
                </el-icon>
              </el-upload>
            </el-form-item>
            <el-form-item label="开始时间" prop="startTime" style="width: 100%">
              <el-date-picker v-model="editForm.startTime" type="datetime" placeholder="请选择" style="width:100%" />
            </el-form-item>
            <el-form-item label="结束时间" prop="endTime" style="width: 100%">
              <el-date-picker v-model="editForm.endTime" type="datetime" placeholder="请选择" style="width:100%" />
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
    </el-drawer>
  </div>
</template>

<script setup>
import { reactive, ref } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import {
  getLiveList,
  addLive,
  updateLive,
  deleteLive,
  getLiveById
} from '@/api/live'
import { isImageMime } from '@/utils/image'
import { isUrl } from '@/utils/validator'
import { formatDate } from '@/utils/format'

const page = ref(1)
const total = ref(0)
const pageSize = ref(10)
const searchInfo = ref({})
const elSearchFormRef = ref(null)
const isDateEndGtStart = (rule, value, callback) => {
  if (value < editForm.value.startTime) {
    callback(new Error("结束时间必须大于开始时间"))
  } else {
    callback()
  }
}
const rules = reactive({
  cover: [
    { required: true, message: '请选择封面', trigger: 'blur' }
  ],
  title: [
    { required: true, message: '请输入标题', trigger: 'blur' }
  ],
  liveTimeline: [
    { required: true, message: '请输入时间线', trigger: 'blur' }
  ],
  liveUrl: [
    { required: true, message: '请输入url', trigger: 'blur' },
    { validator: isUrl, message: '请输入正确的url', trigger: 'blur' }
  ],
  startTime: [
    { required: true, message: '请输入开始时间', trigger: 'blur' }
  ],
  endTime: [
    { required: true, message: '请输入结束时间', trigger: 'blur' },
    { validator: isDateEndGtStart, message: '结束时间必须大于开始时间', trigger: 'blur' }
  ],
  replayUrl: [
    { validator: isUrl, message: '请输入正确的url', trigger: 'blur' }
  ],
})

const initSearchInfo = () => {
  searchInfo.value.keyword = ''
  page.value = 1
}
initSearchInfo()

// 重置
const handleResetSearch = () => {
  initSearchInfo()
  getTableData()
}
// 搜索
const handleSubmitSearch = () => {
  elSearchFormRef.value?.validate(async valid => {
    if (!valid) return
    getTableData()
  })
}

// 查询
const tableData = ref([])
const getTableData = async () => {
  const res = await getLiveList({ page: page.value, pageSize: pageSize.value, ...searchInfo.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()
}

// ----- 以下为 editForm 操作 -----

// 提交表单
const handleFormSubmit = async () => {
  copyTimelineData()

  editFormRef.value.validate(async valid => {
    if (!valid) {
      return false
    }
    let res
    if (isEdit.value) {
      res = await updateLive(editForm.value)
    } else {
      res = await addLive(editForm.value)
    }
    if (res.code === 0) {
      ElMessage({
        type: 'success',
        message: isEdit.value ? '编辑成功' : '添加成功!'
      })
      getTableData()
      initForm()
      dialogFormVisible.value = false
    }
  })
}

// 初始化弹窗内表格方法
const editFormRef = ref(null)
const editForm = ref({})
const checkFlag = ref(false)
const liveTimelineArr = ref([])
const copyTimelineData = () => {
  const arr = liveTimelineArr.value.filter(item => item.title.trim() != '')
  if (arr.length > 0) {
    editForm.value.liveTimeline = JSON.stringify(arr)
  }
}
const timelineAdd = (index) => {
  liveTimelineArr.value.splice(index + 1, 0, { title: '', content: '' })
}
const timelineDel = (index) => {
  liveTimelineArr.value.splice(index, 1)
}
const timelineBlur = (index) => {
  copyTimelineData()
}
const initForm = () => {
  checkFlag.value = false
  liveTimelineArr.value = [{
    title: "",
    content: "",
  }]
  editForm.value = {
    ID: 0,
    title: '',
    brief: '',
    cover: '',
    liveTimeline: '',
    liveUrl: '',
    startTime: '',
    endTime: '',
    replayUrl: '',
  }
}

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

// 删除
const handleDelete = (ID) => {
  ElMessageBox.confirm('此操作将永久删除直播, 是否继续?', '提示', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning'
  })
    .then(async () => {
      const res = await deleteLive({ id: 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 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 getLiveById({ id: ID })
  editForm.value = res.data.live
  if (editForm.value.liveTimeline != '') {
    liveTimelineArr.value = JSON.parse(editForm.value.liveTimeline)
  } else {
    liveTimelineArr.value = [{
      title: "",
      content: ""
    }]
  }
  isEdit.value = true
  dialogFormVisible.value = true
}

// ------- 图片操作 -------
const imgUploadPath = ref(import.meta.env.VITE_BASE_API)
const beforeUpload = (file) => {
  const isLt500K = file.size / 1024 / 1024 < 0.5 // 500K, @todo 应支持在项目中设置
  const isImage = isImageMime(file.type)

  if (!isImage) {
    ElMessage.error('上传图片只能是 jpg,png,svg,webp 格式!')
    return false
  }
  if (!isLt500K && isImage) {
    ElMessage.error('未压缩的上传图片大小不能超过 500KB，请使用压缩上传')
    return false
  }
  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.cover = data.mediaFile.url
}

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

</script>

<style scoped>
.gva-multi-input {
  margin-bottom: 15px;
}
</style>
