<template>
  <div
    id="card_file"
    v-loading="pictLoading"
    class="view"
    element-loading-background="rgba(43, 48, 67, 0.65)"
    element-loading-spinner="el-icon-loading"
  >
    <div class="crm_search">
      <el-form ref="formRef" label-position="" :model="search" label-width="">
        <el-row>
          <el-col :span="24" :md="24" :lg="24">
            <el-form-item>
              <el-select
                v-model="search.lang"
                class="crm-border-radius-no"
                clearable
                :placeholder="$t('Label.Lang')"
                @change="toSearch"
              >
                <el-option
                  v-for="lang in languageOptions"
                  :key="lang.value"
                  :label="$t(lang.label)"
                  :value="lang.value"
                >
                </el-option>
              </el-select>
            </el-form-item>
            <el-form-item>
              <el-button
                class="crm-border-radius-no crm-border-left-no"
                :icon="Search"
                @click="toSearch"
              ></el-button>
            </el-form-item>
          </el-col>
        </el-row>
        <el-form-item>
          <div class="search_action_btn">
            <span class="crm-cursor" @click="toNew">
              <el-icon><Plus /></el-icon>
              <span>{{ $t('Btn.Add') }}</span>
            </span>
            <span
              v-if="display['R-CardFile-Delete']?.show"
              class="crm-cursor delete"
              :class="{ active: multipleSelection.length }"
              @click="toDeleteBatch"
            >
              <el-icon><Minus /></el-icon>
              <span>{{ $t('Btn.Delete') }}</span>
            </span>
          </div>
        </el-form-item>
      </el-form>
    </div>
    <el-table
      :data="mock_tableData"
      stripe
      style="width: 100%"
      @selection-change="handleSelectionChange"
    >
      <el-table-column align="left" type="selection" width="55"> </el-table-column>
      <el-table-column prop="" align="left" :label="$t('system_info.Label.Lang')">
        <template #default="scope">
          <span>
            {{ $t(languageObj[scope.row.lang]) }}
          </span>
        </template>
      </el-table-column>
      <el-table-column prop="addTime" align="left" :label="$t('Label.Date')"> </el-table-column>
      <el-table-column prop="" align="center" :label="$t('Label.Action')">
        <template #default="scope">
          <el-dropdown trigger="click" @command="handleCommand">
            <span class="el-dropdown-link crm-cursor">
              <i style="font-weight: bold; font-size: 20px" class="iconfont iconcaidan"></i>
            </span>
            <template #dropdown>
              <el-dropdown-menu>
                <el-dropdown-item
                  v-if="display['R-CardFile-Update']?.show"
                  :command="{ type: 'editor', row: scope.row }"
                >
                  <el-icon><Edit /></el-icon>
                  <span>{{ $t('Btn.Editor') }}</span>
                </el-dropdown-item>
                <el-dropdown-item
                  v-if="display['R-CardFile-Delete']?.show"
                  :command="{ type: 'delete', id: scope.row.id }"
                >
                  <el-icon><Delete /></el-icon>
                  <span>{{ $t('Btn.Delete') }}</span>
                </el-dropdown-item>
              </el-dropdown-menu>
            </template>
          </el-dropdown>
        </template>
      </el-table-column>
    </el-table>
    <PagePagination
      :pager-info="pagerInfo"
      @size-change="handleSizeChange"
      @current-change="handleCurrentChange"
    />
    <el-dialog
      v-if="dialogCheck"
      v-model="dialogCheck"
      :close-on-click-modal="false"
      :rules="rules"
      :title="isAdd ? $t('R-CardFile-Add') : $t('R-CardFile-Update')"
      width="600px"
    >
      <el-form
        ref="dialogFormRef"
        :model="form"
        :rules="dialogRules"
        class="business-edit-form"
        label-position="right"
        label-width="120px"
      >
        <!-- 语言 -->
        <el-form-item :label="$t('Label.Lang') + '：'" prop="lang">
          <el-select
            v-model="form.lang"
            style="width: 100%"
            :disabled="!isAdd"
            :placeholder="$t('Placeholder.Choose')"
          >
            <el-option
              v-for="lang in languageOptions"
              :key="lang.value"
              :label="$t(lang.label)"
              :value="lang.value"
            >
            </el-option>
          </el-select>
        </el-form-item>
        <!-- ========== setpList 区块 ========== -->
        <el-form-item :label="$t('card.CardFile.p1') + '：'" prop="setpList">
          <div class="steps-wrap">
            <div v-for="(step, idx) in form.setpList" :key="'step-' + idx" class="step-item">
              <div class="step-header">
                <span>{{ $t('card.CardFile.p2') }} {{ step.setp }}</span>
                <div class="step-actions">
                  <el-button
                    type="primary"
                    :icon="Plus"
                    size="small"
                    title="Add step after"
                    @click="addStep(idx)"
                  ></el-button>
                  <el-button
                    v-if="form.setpList.length > 1"
                    type="danger"
                    :icon="Minus"
                    size="small"
                    title="Remove"
                    @click="removeStep(idx)"
                  ></el-button>
                </div>
              </div>

              <el-row :gutter="12" class="step-body">
                <el-col :span="24" style="margin-bottom: 20px">
                  <el-input
                    v-model="step.d"
                    type="textarea"
                    :autosize="{ minRows: 2, maxRows: 10 }"
                    :placeholder="$t('card.CardFile.p3')"
                  ></el-input>
                </el-col>

                <el-col :span="24" style="margin-bottom: 20px">
                  <el-select v-model="step.type" :placeholder="$t('Label.Type')">
                    <el-option
                      v-for="type in uploadTypes"
                      :key="type.value"
                      :label="$t(type.label)"
                      :value="type.value"
                    >
                    </el-option>
                  </el-select>
                </el-col>

                <el-col :span="24" style="margin-bottom: 20px">
                  <div v-if="step.type == '1'">
                    <el-upload
                      :http-request="(opt) => handleFileUpload(opt, idx)"
                      :on-success="handleSuccessStep"
                      accept="image/png, image/jpeg, .jpg, .jpeg, .png"
                      :action="''"
                      :show-file-list="false"
                      drag
                      class="mini-uploader"
                    >
                      <img
                        v-if="step.img"
                        :src="imgUrl + step.img"
                        style="width: 100%; max-height: 80px; object-fit: cover"
                      />
                      <div v-else class="upload-placeholder">{{ $t('card.CardFile.p5') }}</div>
                    </el-upload>
                  </div>
                  <div v-else>
                    <el-input v-model="step.img" :placeholder="$t('card.CardFile.p5')"></el-input>
                  </div>
                </el-col>
              </el-row>
            </div>
          </div>
        </el-form-item>

        <!-- ========== videoList 区块 ========== -->
        <el-form-item :label="$t('card.CardFile.p6') + '：'" prop="videoList">
          <div class="videos-wrap">
            <div v-for="(vitem, vidx) in form.videoList" :key="'video-' + vidx" class="video-item">
              <div class="video-header">
                <span>{{ $t('card.CardFile.p7') }} {{ vidx + 1 }}</span>
                <div class="video-actions">
                  <!-- <el-button type="primary" icon="el-icon-plus" size="mini" @click="addVideo(vidx)"
                    title="Add video after" v-if="form.videoList.length != 2"></el-button>
                  <el-button type="danger" icon="el-icon-minus" size="mini" @click="removeVideo(vidx)"
                    v-if="form.videoList.length > 1" title="Remove"></el-button> -->
                </div>
              </div>

              <el-row :gutter="12" class="video-body">
                <el-col :span="24" style="margin-bottom: 20px">
                  <el-select v-model="vitem.type" :placeholder="$t('Label.Type')">
                    <el-option
                      v-for="type in uploadTypes"
                      :key="type.value"
                      :label="$t(type.label)"
                      :value="type.value"
                    >
                    </el-option>
                  </el-select>
                </el-col>

                <el-col :span="24" style="margin-bottom: 20px">
                  <div v-if="vitem.type == '1'">
                    <el-upload
                      :http-request="(opt) => handleVideoUpload(opt, vidx)"
                      :action="''"
                      :show-file-list="false"
                      :before-upload="beforeAvatarUpload"
                      :on-success="handleSuccessVideo"
                      drag
                      class="mini-uploader"
                    >
                      <video
                        v-if="vitem.fileUrl"
                        :src="imgUrl + vitem.fileUrl"
                        style="width: 100%; max-height: 120px; object-fit: cover"
                        controls
                      ></video>
                      <div v-else class="upload-placeholder">{{ $t('card.CardFile.p9') }}</div>
                    </el-upload>
                  </div>
                  <div v-else>
                    <el-input
                      v-model="vitem.fileUrl"
                      :placeholder="$t('card.CardFile.p8')"
                    ></el-input>
                  </div>
                </el-col>
              </el-row>
            </div>
          </div>
        </el-form-item>
        <el-form-item :label="$t('card.CardFile.p10') + '：'">
          <div class="steps-wrap">
            <div class="step-item">
              <div class="step-header">
                <span>{{ $t('card.CardFile.p10') }} </span>
              </div>
              <el-row :gutter="12" class="step-body">
                <el-col :span="24" style="margin-bottom: 20px">
                  <el-input
                    v-model="form.pdfPassword"
                    :placeholder="$t('card.CardFile.p11')"
                  ></el-input>
                </el-col>
                <el-col :span="24" style="margin-bottom: 20px">
                  <el-upload
                    :http-request="(opt) => handleFileUpload(opt)"
                    :action="''"
                    :show-file-list="false"
                    accept="application/pdf"
                    :on-success="handleSuccessPdf"
                    drag
                    class="mini-uploader"
                  >
                    <div class="upload-placeholder">{{ $t('card.CardFile.p12') }}</div>
                  </el-upload>
                  <a
                    v-if="form.pdfPath"
                    class="upload-pdf"
                    target="_blank"
                    :href="imgUrl + form.pdfPath"
                    controls
                    >{{ form.pdfPath }}</a
                  >
                </el-col>
              </el-row>
            </div>
          </div>
        </el-form-item>
      </el-form>

      <template #footer>
        <div class="dialog-footer">
          <el-button @click="onDialogCancel">{{ $t('Ucard.Business.p32') }}</el-button>
          <el-button type="primary" @click="cardFileAdd">{{ $t('card.Btn.Confirm') }}</el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>

<script setup>
  import { ref, reactive, computed, onMounted, watch, inject } from 'vue'
  import Service from '@/service/ucard'
  import Config from '@/config/index'
  import { handleUpload } from '@/utils/upload'
  import crypt from '@/lib/crypt'
  import PagePagination from '@/components/pagePagination'
  import { JPGs, languageObj, languageOptions } from '@/views/card/CardFile/const'
  import { Delete, Edit, Minus, Plus, Search } from '@element-plus/icons-vue'
  import { useI18n } from 'vue-i18n'

  const { Code } = Config
  const { t } = useI18n()
  const Session = inject('session')
  const pigeon = inject('pigeon')

  // 上传类型选项
  const uploadTypes = [
    { value: '1', label: 'news_add_field.Label.Upload' },
    { value: '2', label: 'news_add_field.Label.Url' },
  ]

  const pictLoading = ref(false)
  const dialogCheck = ref(false)
  const isAdd = ref(true)
  const formRef = ref(null)
  const dialogFormRef = ref(null)

  const form = reactive({
    lang: '',
    tag: '',
    setpList: [{ setp: 1, type: '2', d: '', img: '' }],
    videoList: [
      { type: '2', fileUrl: '', d: '' },
      { type: '2', fileUrl: '', d: '' },
    ],
    pdfPassword: '',
    pdfPath: '',
  })

  const mock_tableData = ref([])
  const search = reactive({
    valid: '',
    tag: '',
    lang: null,
    date: [],
    startDate: '',
    endDate: '',
  })

  const url = Config.Host85
  const imgUrl = Config.Host85
  const imageUrl1 = ref('')
  const uploadDes = ref('')
  const multipleSelection = ref([])

  const tags_options = [
    {
      tag: '1',
      name: 'R-CardFil-tag',
    },
  ]

  const tagMap = {
    1: 'R-CardFil-tag',
  }

  const rules = {
    tag: [
      {
        required: true,
        message: t('vaildate.select.empty'),
        trigger: 'change',
      },
    ],
    lang: [
      {
        required: true,
        message: t('vaildate.select.empty'),
        trigger: 'change',
      },
    ],
    type: [
      {
        required: true,
        message: t('vaildate.select.empty'),
        trigger: 'change',
      },
    ],
    fileUrl: [
      {
        required: true,
        message: t('vaildate.select.empty'),
        trigger: 'change',
      },
    ],
  }

  const pagerInfo = reactive({ row: 10, current: 1, pageTotal: 0, rowTotal: 0 })

  const display = computed(() => {
    return JSON.parse(Session.Get('display', true))
  })

  const AccessToken = computed(() => {
    return {
      'Access-Token': Session.Get('access_token'),
    }
  })

  const dialogRules = computed(() => {
    return {
      lang: [{ required: true, message: t('vaildate.select.empty'), trigger: 'change' }],
      tag: [{ required: true, message: t('vaildate.select.empty'), trigger: 'change' }],
    }
  })

  // 方法定义
  const isPdf = (url) => {
    return /\.pdf(\?.*)?$/i.test(url)
  }

  const handleCommand = (command) => {
    if (command.type == 'delete') {
      multipleSelection.value = [command.id]
      toDeleteBatch(command.id)
    } else if (command.type == 'editor') {
      toUpdate(command.row)
    }
  }

  const handleVideoUpload = (option, index) => {
    handleUpload({ ...option, index }, '/wasabi/card/upload/video')
  }

  const handleFileUpload = (option, index) => {
    handleUpload({ ...option, index }, '/common/upload')
  }

  const handleSuccessStep = (res) => {
    const { index, data } = res
    form.setpList[index].img = data
  }

  const handleSuccessVideo = (res) => {
    const { index, data } = res
    form.videoList[index].fileUrl = data
  }

  const handleSuccessPdf = (res) => {
    const { data } = res
    form.pdfPath = data
  }

  const handleAvatarSuccess1 = (res, file) => {
    if (res.code == 200) {
      if (file && file.raw) {
        imageUrl1.value = URL.createObjectURL(file.raw)
      }
      form.fileUrl = res.data
      uploadDes.value = t('Msg.Success')
    } else {
      // 使用全局message
      console.error('Msg.Fail')
    }
  }

  const beforeAvatarUpload = (file) => {
    const isJPG = JPGs.includes(file.name.split('.').pop())

    const isLt2M = file.size / 1024 / 1024 < 100

    if (!isJPG) {
      pigeon.MessageError(t('Msg.mp4'))
    }
    if (!isLt2M) {
      pigeon.MessageError(t('Msg.10IMG'))
    }
    if (isJPG && isLt2M) {
      uploadDes.value = t('news_add_field.Label.Uploading')
    }
    return isJPG && isLt2M
  }

  const searchFunc = async () => {
    pictLoading.value = true
    if (!display.value['R-CardFile-List']?.show) {
      pigeon.MessageWarning(t('Msg.NotDisplay'))
      pictLoading.value = false
      return
    }

    if (search.date == null || search.date.length == 0) {
      search.startDate = ''
      search.endDate = ''
    } else {
      search.startDate = search.date[0]
      search.endDate = search.date[1]
    }

    let res = await Service.cardFileList({
      ...search,
      page: {
        current: pagerInfo.current,
        row: pagerInfo.row,
      },
    })

    if (res.code == Code.StatusOK) {
      mock_tableData.value = res.data
      if (res.page != null) {
        pagerInfo.rowTotal = res.page.rowTotal
        pagerInfo.pageTotal = res.page.pageTotal
      } else {
        pagerInfo.rowTotal = 0
      }
      pigeon.MessageOK(t('Msg.SearchSuccess'))
      pictLoading.value = false
    } else {
      pigeon.MessageError(res.msg)
      pictLoading.value = false
    }
  }

  const getSearchDate = (e) => {
    search.date = e
  }

  const toSearch = () => {
    pagerInfo.current = 1
    searchFunc()
  }

  const toNew = () => {
    Object.assign(form, {
      lang: '',
      tag: '',
      setpList: [{ setp: 1, type: '2', d: '', img: '' }],
      videoList: [
        { type: '2', fileUrl: '', d: '' },
        { type: '2', fileUrl: '', d: '' },
      ],
      pdfPassword: '',
      pdfPath: '',
    })
    imageUrl1.value = ''
    isAdd.value = true
    dialogCheck.value = true
  }

  const toUpdate = (row) => {
    let parsed = {}
    try {
      parsed =
        typeof row.fileInfo === 'string' && row.fileInfo.trim() ? JSON.parse(row.fileInfo) : {}
    } catch {
      parsed = {}
    }

    Object.assign(form, {
      ...row,
      lang: row.lang || '',
      tag: row.tag || '',
      ...parsed,
      pdfPassword: crypt.Decrypt(row.pdfPassword),
    })

    dialogCheck.value = true
    isAdd.value = false
  }

  const addStep = (afterIndex) => {
    const insertAt = typeof afterIndex === 'number' ? afterIndex + 1 : form.setpList.length
    form.setpList.splice(insertAt, 0, {
      setp: insertAt + 1,
      type: '2',
      d: '',
      img: '',
    })
    reindexSteps()
  }

  const removeStep = (index) => {
    if (form.setpList.length <= 1) return
    form.setpList.splice(index, 1)
    reindexSteps()
  }

  const reindexSteps = () => {
    form.setpList.forEach((s, i) => (s.setp = i + 1))
  }

  const addVideo = (afterIndex) => {
    if (form.videoList.length >= 2) {
      console.warn('最多只能添加两个视频')
      return
    }
    const insertAt = typeof afterIndex === 'number' ? afterIndex + 1 : form.videoList.length
    form.videoList.splice(insertAt, 0, { type: '2', fileUrl: '', d: '' })
  }

  const removeVideo = (index) => {
    if (form.videoList.length <= 1) return
    form.videoList.splice(index, 1)
  }

  const cardFileAdd = async () => {
    if (!dialogFormRef.value) return
    try {
      const valid = await dialogFormRef.value.validate()
      if (!valid) return
    } catch (e) {
      return
    }

    if (!Array.isArray(form.setpList) || form.setpList.length === 0) {
      form.setpList = [{ setp: 1, type: '2', d: '', img: '' }]
    }
    if (!Array.isArray(form.videoList) || form.videoList.length === 0) {
      form.videoList = [{ type: '2', fileUrl: '', d: '' }]
    }

    let res
    const payload = {
      ...form,
      type: '1',
      fileInfo: JSON.stringify({
        setpList: form.setpList,
        videoList: form.videoList,
      }),
      pdfPassword: crypt.Encrypt(String(form.pdfPassword)),
    }

    if (isAdd.value) {
      res = await Service.cardFileAdd(payload)
    } else {
      res = await Service.cardFileUpdate(payload)
    }

    if (res && res.code == 200) {
      toNew()
      dialogCheck.value = false
      pigeon.MessageOK(t('Msg.Success'))
      searchFunc()
    } else {
      pigeon.MessageError(res.msg || t('Msg.Fail'))
    }
  }

  const onDialogCancel = () => {
    dialogCheck.value = false
  }

  const toDeleteBatch = async () => {
    if (!multipleSelection.value.length) {
      return
    }
    pigeon.MessageConfirm(
      t('Msg.Delete'),
      t('Msg.SystemPrompt'),
      t('Btn.Confirm'),
      t('Btn.Cancel'),
      async () => {
        let ids = []
        ids.push(id)
        let res = await Service.cardFileDelete({ ids: multipleSelection.value })
        if (res.code == Code.StatusOK) {
          pigeon.MessageOK(t('Msg.DeleteSuccess'))
          searchFunc()
        } else {
          pigeon.MessageError(res.msg)
        }
      },
      () => {}
    )
  }

  const handleSelectionChange = (val) => {
    multipleSelection.value = val.map((item) => item.id)
  }

  const handleSizeChange = (val) => {
    pagerInfo.row = val
    searchFunc()
  }

  const handleCurrentChange = (val) => {
    pagerInfo.current = val
    searchFunc()
  }

  onMounted(() => {
    searchFunc()
  })

  watch(
    () => form.type,
    () => {
      // form.fileUrl = ''
    }
  )
</script>

<style scoped lang="scss">
  @import 'index.scss';
</style>
