<template>
  <div class="print">
    <div class="print-wrapper" v-if="!isPrint">
      <div class="left">
        <div class="left-wrapper">
          <div class="title">基础元素</div>
          <div class="left-item__wrapper">
            <div class="ep-draggable-item item" tid="defaultModule.text">
              <i class="iconfont">&#xe649;</i>
              <span>文本</span>
            </div>
            <div class="ep-draggable-item item" tid="defaultModule.longText">
              <i class="iconfont">&#xe7dc;</i>
              <span>长文</span>
            </div>
            <div class="ep-draggable-item item" tid="defaultModule.table">
              <i class="iconfont">&#xea3f;</i>
              <span>表格</span>
            </div>
          </div>
          <div class="title">辅助元素</div>
          <div class="left-item__wrapper">
            <div class="ep-draggable-item item" tid="defaultModule.hline">
              <i class="iconfont">&#xe7dd;</i>
              <span>横线</span>
            </div>
            <div class="ep-draggable-item item" tid="defaultModule.vline">
              <i class="iconfont">&#xe70f;</i>
              <span>竖线</span>
            </div>
            <div class="ep-draggable-item item" tid="defaultModule.rect">
              <i class="iconfont">&#xe620;</i>
              <span>矩形</span>
            </div>
            <div class="ep-draggable-item item" tid="defaultModule.oval">
              <i class="iconfont">&#xe76a;</i>
              <span>圆形</span>
            </div>
          </div>
          <div class="title">常用元素</div>
          <div class="left-item__wrapper" id="custom-provider">
          </div>
          <div class="title">
            <span>素材</span>
          </div>
          <div class="left-item__wrapper">
            <div
              class="item"
              style="cursor: pointer;"
              @click="search.type = 1, search.current = 1, isShowImage = true, getConfig()">
              <div>图片素材</div>
            </div>
            <div
              class="item"
              style="cursor: pointer;"
              @click="search.type = 0, search.current = 1, isShowImage = true, getConfig()">
              <div>文字素材</div>
            </div>
          </div>
          <div class="title">
            <span>动态数据（如日期）</span>
            <el-button type="primary" size="mini" @click="addField">添加</el-button>
          </div>
          <div class="left-item__wrapper">
            <div
              class="item"
              v-for="(item, index) in dynamicFromList"
              :key="index"
              style="cursor: pointer;"
              @click="addItemToCanvas(item.fieldName)">
              <div>{{ item.fieldName }}</div>
              <span class="el-icon-error" @click.stop="removeField(index)"></span>
            </div>
          </div>
        </div>
      </div>
      <div class="center">
        <div class="center-header">
          <div class="paper">
            <el-button-group size="small">
              <template v-for="(value, type) in paperTypes">
                <el-button size="small" :type="curPaperType === type ? 'primary' : ''" @click="setPaper(type,value)" :key="type">
                  {{ type }}
                </el-button>
              </template>
              <el-popover v-model="paperPopVisible" placement="top" :width="260" trigger="click">
                <div>
                  <div style="font-size: 16px; font-weight: bold">设置纸张宽高(mm)</div>
                  <div style="margin-top: 10px">
                    <el-input size="small" style="margin-bottom: 10px" v-model="paperWidth" type="number" placeholder="宽(mm)" />
                    <el-input size="small" v-model="paperHeight" type="number" placeholder="高(mm)" />
                  </div>
                  <el-button style="margin-top: 12px" size="small" @click.stop="setPaperOther">确定</el-button>
                </div>
                <el-button slot="reference" size="small" :type="'other' == curPaperType ? 'primary' : ''">自定义纸张</el-button>
              </el-popover>
            </el-button-group>
            <el-button @click="isShowTemplate = true" type="warning" size="small" style="margin-left: 10px;">模板库</el-button>
          </div>
        </div>
        <div class="center-wrapper">
          <div id="hiprint-printTemplate"></div>
        </div>
      </div>
      <div class="right">
        <div id="PrintElementOptionSetting"></div>
      </div>
    </div>
    <ai-dialog :visible.sync="isShowPreview" title="预览" width="1200" customFooter>
      <div class="print-viewer" v-html="html"></div>
      <div class="dialog-footer" slot="footer">
        <el-button @click="isShowPreview = false">取消</el-button>
      </div>
    </ai-dialog>
    <ai-dialog :visible.sync="isShowImage" title="图片/文字素材" width="960" customFooter>
      <el-select v-model="search.type" placeholder="请选择图片/文字素材" size="small" @change="search.current = 1, getConfig()">
        <el-option label="图片素材" :value="1"></el-option>
        <el-option label="文字素材" :value="0"></el-option>
      </el-select>
      <ai-table
        v-if="search.type === 1"
        :tableData="tableData"
        :col-configs="colConfigs"
        :total="total"
        :current.sync="search.current"
        :size.sync="search.size"
        style="margin-top: 8px;"
        height="400"
        @getList="getConfig">
        <el-table-column slot="image" label="图片" align="left">
          <template v-slot="{ row }">
            <el-image
              v-if="search.type === 1"
              style="width: 80px; height: 80px"
              :src="row.imgUrl"
              :preview-src-list="[row.imgUrl]">
            </el-image>
          </template>
        </el-table-column>
        <el-table-column slot="options" label="操作" align="center">
          <template v-slot="{ row }">
            <div class="table-options">
              <el-button type="text" @click="row.type === '1' ? addImage(row.imgUrl) : addText(row.contents), isShowImage = false">添加</el-button>
            </div>
          </template>
        </el-table-column>
      </ai-table>
      <ai-table
        v-if="search.type === 0"
        :tableData="tableData"
        :col-configs="colConfigs"
        :total="total"
        :current.sync="search.current"
        :size.sync="search.size"
        style="margin-top: 8px;"
        height="400"
        @getList="getConfig">
        <el-table-column slot="options" label="操作" align="center">
          <template v-slot="{ row }">
            <div class="table-options">
              <el-button type="text" @click="row.type === '1' ? addImage(row.imgUrl) : addText(row.contents), isShowImage = false">添加</el-button>
            </div>
          </template>
        </el-table-column>
      </ai-table>
      <div class="dialog-footer" slot="footer">
        <el-button @click="isShowImage = false">取消</el-button>
      </div>
    </ai-dialog>
    <ai-dialog
      :visible.sync="isShowDynamicForm"
      title="动态数据"
      width="590px"
      @confirm="onConfirm">
      <el-form :model="dynamicFrom" ref="form" label-width="100px">
        <el-form-item
          label="数据名称："
          :prop="`field_${dynamicFromList.length > 9 ? dynamicFromList.length + 1 : '0' + (dynamicFromList.length + 1)}`"
          :rules="[{ required: true, message: '请输入数据名称', trigger: 'blur' }]">
          <el-input placeholder="请输入数据名称" type="text" v-model="dynamicFrom[`field_${dynamicFromList.length > 9 ? dynamicFromList.length + 1 : '0' + (dynamicFromList.length + 1)}`]"></el-input>
        </el-form-item>
      </el-form>
    </ai-dialog>
    <ai-dialog :visible.sync="isShowTemplate" title="模板库" width="960" customFooter>
      <ai-table
        :tableData="templateList"
        :col-configs="templateColConfigs"
        :total="templateTotal"
        :current.sync="searchTemplate.current"
        :size.sync="searchTemplate.size"
        style="margin-top: 8px;"
        height="400"
        @getList="getTemplateList"
        v-loading="templateLoading">
        <el-table-column slot="options" label="操作" align="center" width="200">
          <template v-slot="{ row }">
            <div class="table-options">
              <el-button type="text" @click="showTemplate(row)">模板预览</el-button>
              <el-button type="text" @click="updateTempate(row)">使用</el-button>
            </div>
          </template>
        </el-table-column>
      </ai-table>
      <div class="dialog-footer" slot="footer">
        <el-button @click="isShowImage = false">取消</el-button>
      </div>
    </ai-dialog>
  </div>
</template>

<script>
  import { hiprint, defaultElementTypeProvider, disAutoConnect } from 'vue-plugin-hiprint'
  import { newHiprintPrintTemplate } from '@/utils/template-helper'
  import { customProvider } from './customProvider'

  disAutoConnect()

  export default {
    props: {
      list: {
        type: Array,
        default: () => {
          return []
        }
      },

      params: {
        type: Array,
        default: () => {
          return []
        }
      },

      printData: {
        type: Object,
        default: () => {
          return {
          }
        }
      },

      template: {
        type: Object,
        default: () => {
          return {
            "panels": [{
              "index": 0,
              "name": 1,
              "height": 200,
              "width": 200,
              "printElements": [],
              "paperNumberDisabled": true,
              "paperNumberContinue": true,
              "fontFamily": "Microsoft YaHei",
              "watermarkOptions": {}
            }]
          }
        }
      },

      isPrint: {
        type: Boolean,
        default: false
      }
    },

    data () {
      return {
        html: '',
        isShowPreview: false,
        hiprintTemplate: null,
        isShowTemplate: false,
        templateList: [],
        curPaper: {
          type: 'other',
          width: 200,
          height: 200
        },
        paperTypes: {
          '100 * 100': {
            width: 200,
            height: 200
          },
          '100 * 80': {
            width: 200,
            height: 160
          },
          '80 * 60': {
            width: 160,
            height: 120
          },
          '60 * 40': {
            width: 120,
            height: 80
          }
        },
        paperPopVisible: false,
        paperWidth: 200,
        paperHeight: 200,
        isShowDynamicForm: false,
        dynamicFrom: {
        },
        dynamicFromList: [],
        panel: null,
        contents: [],
        images: [],
        search: {
          current: 1,
          size: 10,
          type: 1
        },
        searchTemplate: {
          current: 1,
          size: 10,
          type: 1
        },
        templateTotal: 0,
        isShowImage: false,
        tableData: [],
        total: 0,
        templateColConfigs: [
          { prop: 'name', label: '模板名称', align: 'left' }
        ],
        templateLoading: false
      }
    },

    watch: {
      template: {
        handler(value) {
          if (value && this.hiprintTemplate && !this.isPrint) {
            const config = value.panels[0]
            this.hiprintTemplate.update(value)
            this.curPaper = {type: 'other', width: config.width, height: config.height}
            this.hiprintTemplate.setPaper(config.width, config.height)

            if (this.params) {
              this.dynamicFromList = this.params
            }
          }
        },
        deep: true
      }
    },

    computed: {
      curPaperType() {
        let type = 'other'
        let types = this.paperTypes
        for (const key in types) {
          let item = types[key]
          let {width, height} = this.curPaper
          if (item.width === width && item.height === height) {
            type = key
          }
        }
        return type
      },

      colConfigs () {
        if (this.search.type === 1) {
          return [
            { slot: 'image' },
            { prop: 'remark', label: '描述', align: 'center' }
          ]
        }

        return [
          { prop: 'contents', label: '文本', align: 'center' },
          { prop: 'remark', label: '描述', align: 'center' }
        ]
      }
    },

    mounted() {
      if (this.isPrint) {
        this.hiprintTemplate = newHiprintPrintTemplate('temulables')
      } else {
        hiprint.init({
          providers: [defaultElementTypeProvider(), customProvider({})]
        })
        this.buildLeftElement()
        this.buildDesigner()
        this.getConfig()

        this.getTemplateList()
      }
    },

    methods: {
      addField() {
        const num = this.dynamicFromList.length > 9 ? this.dynamicFromList.length + 1 : `0${this.dynamicFromList.length + 1}`

        // eslint-disable-next-line no-empty
        if (this.dynamicFromList.length && !this.dynamicFromList.at(-1)[`field_${num}`]) {
        } else {
          this.$set(this.dynamicFrom, `field_${num}`, '')
        }

        this.isShowDynamicForm = true
      },

      removeField(index) {
        this.dynamicFromList.splice(index, 1)
      },

      updateTempate(row) {
        this.templateLoading = true
        this.$http.post(`/api/templateRecommend/detail?id=${row.id}`).then(res => {
          if (res.code === 0) {
            const config = JSON.parse(res.data.content)
            this.hiprintTemplate.update(config)
            this.hiprintTemplate.setPaper(config.panels[0].width, config.panels[0].height)

            this.dynamicFromList = JSON.parse(res.data.params)
            this.isShowTemplate = false
          }

          this.templateLoading = false
        })
      },

      getTemplateList() {
        this.$http.post(`/api/templateRecommend/getRecommendPage`, null, {
          params: this.searchTemplate
        }).then(res => {
          if (res.code === 0) {
            this.templateList = res.data.records
            this.templateTotal = res.data.total
          }
        })
      },

      showTemplate (row) {
        this.templateLoading = true
        this.$http.post(`/api/templateRecommend/detail?id=${row.id}`).then(res => {
          this.templateLoading = false
          if (res.code === 0) {
            this.html = res.data.codes
            this.isShowPreview = true
          }
        })
      },

      getConfig() {
        this.$http.post(`/api/material/getPage?current=${this.search.current}&size=${this.search.size}&type=${this.search.type}`).then(res => {
          if (res.code === 0) {
            this.tableData = res.data.records
            this.total = res.data.total
          }
        })
      },

      addImage(src) {
        this.panel.addPrintImage({
          options: {
            title: '',
            left: 70.5,
            top: 58.5,
            src: src,
            width: 100,
            height: 100
          }
        })
        const el = this.hiprintTemplate.printPanels[0].printElements.at(-1)
        const designPaper = this.hiprintTemplate.printPanels[0].designPaper
        this.hiprintTemplate.printPanels[0].appendDesignPrintElement(designPaper, el, true)
        el.design(void 0, designPaper)
      },

      addText(text, isSetField = false) {
        this.panel.addPrintText({
          options: {
            field: isSetField ? text : '',
            testData: isSetField ? text : '',
            title: isSetField ? '' : text,
            left: 70.5,
            top: 58.5,
            width: 140,
            height: 20,
            coordinateSync: true,
            contentPaddingLeft: 5.25,
            textContentVerticalAlign: 'middle',
            widthHeightSync: true,
            hideTitle: true,
            fontFamily: 'Microsoft YaHei',
            fontWeight: '700'
          }
        })
        const el = this.hiprintTemplate.printPanels[0].printElements.at(-1)
        const designPaper = this.hiprintTemplate.printPanels[0].designPaper
        this.hiprintTemplate.printPanels[0].appendDesignPrintElement(designPaper, el, true)
        el.design(void 0, designPaper)
      },

      addItemToCanvas(name) {
        this.addText(name, true)
      },

      onConfirm() {
        this.$refs.form.validate((valid) => {
          if (valid) {
            const num = this.dynamicFromList.length > 9 ? this.dynamicFromList.length + 1 : `0${this.dynamicFromList.length + 1}`
            this.dynamicFromList.push({
              fieldValue: `field_${num}`,
              fieldName: this.dynamicFrom[`field_${num}`]
            })
            this.isShowDynamicForm = false
          }
        })
      },

      buildLeftElement() {
        // eslint-disable-next-line no-undef
        hiprint.PrintElementTypeManager.buildByHtml($('.ep-draggable-item'))
        // eslint-disable-next-line no-undef
        $('#custom-provider').empty()
        // eslint-disable-next-line no-undef
        hiprint.PrintElementTypeManager.build($('#custom-provider'), 'customProvider')
      },

      buildDesigner() {
        // eslint-disable-next-line no-undef
        $('#hiprint-printTemplate').empty()
        this.hiprintTemplate = newHiprintPrintTemplate('temulables', {
          template: this.template,
          settingContainer: '#PrintElementOptionSetting',
          onImageChooseClick: (target) => {
            let input = document.createElement('input')
            input.setAttribute('type', 'file')
            input.click()
            input.onchange = function () {
              var file = this.files[0]
              if (file) {
                var reader = new FileReader()
                reader.readAsDataURL(file)
                reader.onloadend = function () {
                  target.refresh(reader.result)
                }
              }
            }
            input.remove()
          }
        })


        this.$nextTick(() => {
          this.hiprintTemplate.design('#hiprint-printTemplate', {
            grid: true
          })

          this.panel = this.hiprintTemplate.printPanels[0]
        })
      },

      setPaperOther () {
        let value = {}
        value.width = this.paperWidth
        value.height = this.paperHeight
        this.setPaper('other', value)
        this.paperPopVisible = false
      },

      setPaper(type, value) {
        try {
          if (Object.keys(this.paperTypes).includes(type)) {
            this.curPaper = {type: type, width: value.width, height: value.height}
            this.hiprintTemplate.setPaper(value.width, value.height)
          } else {
            this.curPaper = {type: 'other', width: value.width, height: value.height}
            this.hiprintTemplate.setPaper(value.width, value.height)
          }
        } catch (error) {
          this.$message.error(`操作失败: ${error}`)
        }
      },

      print() {
        this.hiprintTemplate.print(this.printData)
      },

      // js打印（不显示设计界面）
      toPrint (template, printData) {
        this.hiprintTemplate = newHiprintPrintTemplate('temulables')

        setTimeout(() => {
          this.hiprintTemplate.update(template)
          this.hiprintTemplate.print(printData)
        }, 100)
      },

      elementToString(el) {
        const node = document.createElement('div')
        node.innerHTML = el.html()

        document.querySelector('body').appendChild(node)
        const html = node.innerHTML

        document.querySelector('body').removeChild(node)
        return html
      },

      savePdf() {
        this.hiprintTemplate.toPdf(this.printData, '测试导出pdf',{scale:2 }).then(v => {
          console.log(v)
        })
      },

      save() {
        const html = this.elementToString(this.hiprintTemplate.getHtml(this.printData))
        const json = this.hiprintTemplate.getJson()

        return {
          html,
          json,
          params: JSON.stringify(this.dynamicFromList)
        }
      },

      preview() {
        this.html = this.elementToString(this.hiprintTemplate.getHtml(this.printData))
        this.isShowPreview = true
      },

      getHtml() {
        return this.elementToString(this.hiprintTemplate.getHtml(this.printData))
      },

      clearPaper() {
        this.hiprintTemplate.clear()
      },

      exportJson() {
        return this.hiprintTemplate.getJson()
      }
    }
  }
</script>

<style lang="scss" scoped>
  .print {
    height: 100%;

    .temuBarCode {
      display: flex;
      flex-direction: column;
      padding: 1pt 3pt;
    }

    .print-wrapper {
      display: flex;
      height: calc(100vh - 180px);

      ::v-deep(.prop-tab-items) {
        background-color: transparent !important;

        .prop-tab-item {
          background-color: transparent !important;

          .tab-title {
            font-size: 14px;
          }
        }
      }

      ::v-deep(.hiprint-option-items .hiprint-option-item-label) {
        width: 100%;
        margin-bottom: 14px;
        text-align: left;
        font-size: 14px;
      }

      ::v-deep(.hiprint-printPanel) {
        display: block;

        .dynamicField {
          background-color: #bfc2e9;
          border-color: #bfc2e9;
        }
      }

      ::v-deep(.minicolors) {
        flex: 1;
        width: inherit;

        input {
          width: 100% !important;
        }
      }

      ::v-deep(.hiprint-option-item-field) {
        width: 100%;
        font-size: 14px;

        input {
          height: 24px;
        }
      }

      ::v-deep(.hiprint-option-item-row) {
        display: block;
      }

      ::v-deep(.prop-tab-items) {
        margin-bottom: 10px;
      }

      ::v-deep(.hiprint-option-items),
      ::v-deep(.prop-tabs) {
        background-color: transparent !important;
      }

      .left {
        width: 350px;
        height: 100%;
        overflow-y: auto;

        .title {
          display: flex;
          align-items: center;
          justify-content: space-between;
          width: 320px;
          margin: 14px 0;
        }

        .left-item__wrapper {
          display: flex;
          flex-wrap: wrap;
          margin-bottom: 10px;

          .item {
            display: flex;
            position: relative;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            left: 0!important;
            top: 0!important;
            width: 100px;
            margin-bottom: 10px;
            margin-right: 10px;
            padding: 10px 0;
            background-color: #eee;
            border-radius: 4px;

            &:nth-of-type(3n) {
              margin-right: 0;
            }

            i {
              margin-bottom: 10px;
            }

            .el-icon-error {
              position: absolute;
              top: -6px;
              right: -6px;
              color: red;
              font-size: 18px;
              cursor: pointer;
            }
          }

          ::v-deep(ul) {
            margin: 0;
            padding: 0;
            list-style: none;

            .title {
              display: none;
            }

            ul {
              display: flex;
              flex-wrap: wrap;
              margin-bottom: 10px;

              li {
                display: flex;
                flex-direction: column;
                align-items: center;
                justify-content: center;
                width: 100px;
                margin-bottom: 10px;
                margin-right: 10px;
                background-color: #eee;
                border-radius: 4px;

                &:nth-of-type(3n) {
                  margin-right: 0;
                }

                a {
                  margin-top: 10px;
                  padding: 10px 0;
                }
              }
            }
          }
        }
      }

      .center {
        display: flex;
        position: relative;
        flex-direction: column;
        flex: 1;
        overflow: hidden;
        padding: 0 10px;
        color: #000;

        .center-wrapper {
          flex: 1;
          overflow-x: auto;
          overflow-y: auto;
          width: 100%;
          padding: 20px 20px 10px;
        }

        .center-header {
          width: 100%;
          padding-bottom: 10px;

          .paper {
            display: flex;
            position: relative;
            align-items: center;
            justify-content: center;
          }

          .scale {
            display: flex;
            align-items: center;
            margin: 0 10px;
          }
        }
      }

      .right {
        width: 300px;
        overflow-y: auto;
        overflow-x: hidden;
      }
    }

    .print-viewer {
      color: #000;
    }
  }
</style>
