<template>
  <div
    :style="{ width: record.options.width }"
    class="upload-img-box-9136076486841527"
  >
    <a-upload
      name="file"
      :multiple="record.options.multiple"
      :listType="record.options.listType"
      :disabled="record.options.disabled"
      :data="optionsData"
      :fileList="fileList"
      :action="uploadAction"
      :headers="headers"
      accept="image/gif, image/jpeg, image/png"
      @change="handleChange"
      @preview="handlePreview"
      :remove="remove"
      :beforeUpload="beforeUpload"
    >
      <a-button
        v-if="record.options.listType !== 'picture-card' && fileList.length < record.options.limit"
        :disabled="record.options.disabled"
      >
        <ych-icon type="upload"/>
        {{LocleUtil.getLocale('m.common.button.upload')}}
      </a-button>
      <div
        v-if="record.options.listType === 'picture-card' && fileList.length < record.options.limit"
        :disabled="record.options.disabled"
      >
        <ych-icon type="plus"/>
        <div class="ant-upload-text">{{ LocleUtil.getLocale('m.common.button.upload') }}</div>
      </div>
    </a-upload>
    <!--  图片列表 v-show="this.fileList && this.fileList.length > 0" -->
    <div :style="previewContainerStyle">
      <!--v-show="record.options.showIsolatePreview  :style="previewContainerStyle"-->
      <ul :id="imagesId" class="cm-preview-images">
        <li v-for="file in fileList" :class="previewItemCls">
          <img :src="file.url" :alt="file.name">
        </li>
      </ul>
    </div>
    <a-modal
      :maskClosable="false"
      :keyboard="false"
      :visible="previewVisible"
      :footer="null"
      @cancel="handleCancel">
      <img alt="example" style="width: 100%" :src="previewImageUrl"/>
    </a-modal>
  </div>
</template>

<script>

import {deleteAction, getFileAccessHttpUrl} from '../utils/manage'
import YchConstant from "../utils/YchConstant";
import TokenStorageUtil from "../utils/TokenStorageUtil";
import 'viewerjs/dist/viewer.css';
import Viewer from 'viewerjs';
import {uuid} from 'vue-uuid'
import LocleUtil from "../utils/LocleUtil";

export default {
    name: 'UploadImg',
    data () {
      return {
        uploadAction: YchConstant.PREFIX_REQUEST + YchConstant.PREFIX_SYSTEM + '/common/upload',
        headers: {},
        fileList: [],
        previewImageUrl: '',
        previewVisible: false,
        deleteUrl: YchConstant.PREFIX_SYSTEM + '/common/deleteFile',
        pageViewer: null,
        options: {
          url: 'src',
          inline: true,
          navbar: false
        },
        resizeInit: false,
        previewContainerStyle: {
          border: '1px dotted #666161'
        },
        previewItemCls: '',
        /**
         * 图片预览相关
         */
        imagesId: 'images_' + uuid.v1(),
      }
    },
    props: {
      record: {
        type: Object,
        required: true,
      },
      value: {
        type: String,
      }
    },
    components: {
      Viewer
    },
    computed: {
      LocleUtil() {
        return LocleUtil
      },
      optionsData () {
        return {
          biz: this.record.options.bizPath || 'temp'
        }
      },
    },
    watch: {
      value: {
        handler (val, old) {
          //handler before created and mounted
          this.fileList = val ? JSON.parse(val) : []

          if (this._isMounted) {
            if (this.fileList.length === 0) {
              if (this.pageViewer) {
                this.pageViewer.destroy()
                this.pageViewer = null
                this.initViewer()
              }
            } else {
              this.$nextTick(() => {
                this.pageViewer.update()
              })
            }
          }
      },
        immediate: true
      }
    },
    created () {
      const token = TokenStorageUtil.get()
      this.headers = { 'X-Access-Token': token }
      //determine inline mode, calc width and height
      this.options.inline = typeof this.record.options.showIsolatePreview === 'undefined' ? false : this.record.options.showIsolatePreview;
      this.previewContainerStyle.display = this.options.inline ? 'block' : 'none'
      this.calcPreviewLayout()
    },
    mounted() {
      this.setViewerNdListener()
    },
    onUnmounted() {
      if (this.resizeInit) {
        window.removeEventListener("resize", this.resizePreviewArea);
        this.resizeInit = false
      }
    },
    methods: {
      handleSelectChange () {
        setTimeout(() => {
          const arr = this.fileList.map(item => {
            if (typeof item.response !== 'undefined') {
              const res = item.response
              return {
                type: 'img',
                name: item.name,
                status: item.status,
                uid: item.uid,
                url: getFileAccessHttpUrl(res.message) || ''
              }
            } else {
              return {
                type: 'img',
                name: item.name,
                status: item.status,
                uid: item.uid,
                url: getFileAccessHttpUrl(item.url) || ''
              }
            }
          })

          const arrString = arr.length > 0 ? JSON.stringify(arr) : ''
          this.$emit('change', arrString)
          this.$emit('input', arrString)
        }, 10)
      },
      // 预览
      handlePreview (file) {
        //定位到选中的图片位置
        let previewIdx = 0
        for(let idx = 0; idx < this.fileList.length; idx ++) {
          if (file.url === this.fileList[idx].url) {
            previewIdx = idx;
            break
          }
        }
        this.$nextTick(() => {
          this.pageViewer.view(previewIdx);
        })
        // this.previewImageUrl = file.url || file.thumbUrl
        // this.previewVisible = true
      },
      handleCancel () {
        this.previewVisible = false
      },
      remove (file) {
        return new Promise((resovle, reject) => {
          const that = this
          this.$confirm({
            title: LocleUtil.getLocale('m.common.title.delete'),
            okText: LocleUtil.getLocale('m.common.button.ok'),
            cancelText: LocleUtil.getLocale('m.common.button.cancel'),
            content: LocleUtil.getLocale('m.eform.formDesign.label.shi-fou-shan-chu-filename', [file.name]),
            onOk () {
              deleteAction(that.deleteUrl, { url: file.url }).then((res) => {
                if (res.success) {
                  resovle(true)
                  that.handleSelectChange()
                } else {
                  that.$message.error(`删除失败.`)
                  resovle(false)
                }
              })
            },
            onCancel () {
              resovle(false)
            }
          })
        })
      },
      handleChange (info) {
        // 上传数据改变时
        this.fileList = info.fileList
        if (info.file.status === 'done') {
          if (info.file.response.success) {
            this.handleSelectChange()
          } else {
            this.fileList.pop()
            this.$message.error(LocleUtil.getLocale('m.eform.formDesign.label.infofilename-shang-chuan-shi-bai', [info.file.name]))
          }
        } else if (info.file.status === 'error') {
          this.fileList.pop()
          this.$message.error(LocleUtil.getLocale('m.eform.formDesign.label.infofilename-shang-chuan-shi-bai', [info.file.name]))
        }
      },
      beforeUpload (file, files) {
        if (files.length + this.fileList.length > this.record.options.limit) {
          this.$message.warning(LocleUtil.getLocale('m.eform.formDesign.label.zui-da-shang-chuan-shu-liang-wei-thisrecordoptionslimit', [this.record.options.limit]))
          files.splice(this.record.options.limit - this.fileList.length)
        }
      },
      initViewer() {
        if (!this.pageViewer) {
          this.pageViewer = new Viewer(document.getElementById(this.imagesId),  this.options);
        }
      },
      resizePreviewArea() {
        let uploadImageEle = document.getElementById(this.imagesId) && document.getElementById(this.imagesId).parentNode && document.getElementById(this.imagesId).parentNode.parentNode
        let ratio = 1;
        if (this.record.options.isolatePreviewAspectWidth > 0 && this.record.options.isolatePreviewAspectHeight > 0) {
          ratio = this.record.options.isolatePreviewAspectHeight / this.record.options.isolatePreviewAspectWidth;
        }

        let percent = Number.parseInt(this.previewContainerStyle.width.replaceAll('%', ''))
        if (uploadImageEle){
          this.previewContainerStyle.height =  Number.parseInt(uploadImageEle.getBoundingClientRect().width * ratio * percent / 100+ '') + 'px';
        }
        //getScreenRatio() *
      },
      calcPreviewLayout() {
          let rowCnt = 1
          let colCnt = 1
          switch (this.record.options.limit) {
            case 1:
              this.previewItemCls = 'cm-preview-item-1-1'
              break
            case 2:
              colCnt = 2
              this.previewItemCls = 'cm-preview-item-1-2'
              break
            case 3:
              colCnt = 3
              this.previewItemCls = 'cm-preview-item-1-3'
              break
            case 4:
              rowCnt = 2
              colCnt = 2
              this.previewItemCls = 'cm-preview-item-2-2'
              break
            case 5:
            case 6:
              rowCnt = 2
              colCnt = 3
              this.previewItemCls = 'cm-preview-item-2-3'
              break
            default:
              rowCnt = 3
              colCnt = 3
              this.previewItemCls = 'cm-preview-item-3-3'
              break
          }
      },
      setViewerNdListener() {
        let previewAreaWidth = '100%'
        if (/^\d+(px|%)$/.test(this.record.options.isolatePreviewWidth)) {
          previewAreaWidth = this.record.options.isolatePreviewWidth
        } else if (this.record.options.isolatePreviewWidth) {
          previewAreaWidth = this.record.options.isolatePreviewWidth + 'px'
        }
        this.previewContainerStyle.width = previewAreaWidth

        if (previewAreaWidth.includes('%')) {
          if (!this.resizeInit) {
            window.addEventListener("resize", this.resizePreviewArea);
          }
          this.resizePreviewArea();
        } else {
          let previewAreaWidthInNum = Number.parseInt(previewAreaWidth.match(new RegExp(/\d+/))[0])

          let ratio = 1;
          if (this.record.options.isolatePreviewAspectWidth > 0 && this.record.options.isolatePreviewAspectHeight > 0) {
            ratio = this.record.options.isolatePreviewAspectHeight /  this.record.options.isolatePreviewAspectWidth;
          }
          this.previewContainerStyle.height = Number.parseInt(previewAreaWidthInNum * ratio + '') + 'px';
        }

        //初始化组件，注意 imagesId: uuid.v1()保证唯一性多个不相互干扰
        this.$nextTick(() => {
          this.initViewer();
        })
      }
    },
    model: {
      prop: 'value',
      event: 'change'
    }
  }
</script>
<style lang="css" scoped>
/deep/ .ant-modal-close-x {
  display: inline!important;
  width: 56px;
  height: 56px;
  font-size: 21px;
  font-style: normal;
  line-height: 0;
  text-align: center;
  text-transform: none;
  text-rendering: auto;
}
</style>
<style lang="less">
  .upload-img-box-9136076486841527 {
    /* you can make up upload button and sample style by using stylesheets */

    .ant-upload-select-picture-card i {
      font-size: 32px;
      color: #999;
    }

    .ant-upload-select-picture-card .ant-upload-text {
      margin-top: 8px;
      color: #666;
    }
  }

  .cm-preview-images {
    margin: 0;
    padding: 10px;
    display: flex;
    flex-wrap: wrap;
    width: 100%;
    height: 100%;
    align-items: center;
  }
  .cm-preview-images li {
    list-style: none;
    display: inline-flex;
    justify-content: center;
    align-items: center;
    box-sizing: border-box;
    padding: 5px;
  }
  .cm-preview-images li img {
    max-width: 100%;
    max-height: 100%;
  }
  .cm-preview-item-1-1 {
    width: 100%;
    height: 100%;
  }
  .cm-preview-item-1-2 {
    width: 50%;
    height: 100%;
  }
  .cm-preview-item-1-3 {
    width: 33.333%;
    height: 100%;
  }
  .cm-preview-item-2-2 {
    width: 50%;
    height: 50%;
  }
  .cm-preview-item-2-3 {
    width: 33.333%;
    height: 50%;
  }
  .cm-preview-item-3-3 {
    width: 33.333%;
    height: 33.333%;
  }
</style>
