<template>
  <div>
    <el-dialog
      :title="title"
      :width="type == 'import' ? '900px' : '1200px'"
      top="5vh"
      :visible.sync="dialogShow"
      :close-on-click-modal="false"
      @close="closeDialog"
    >
      <div class="dt-button-group">
        <el-button
          type="primary"
          icon="el-icon-plus"
          @click="openAddFieldsDialog"
          >添加字段</el-button
        >
      </div>

      <el-table
        v-loading="loading"
        border
        stripe
        class="dt-table"
        ref="DTTable"
        row-key="key"
        :data="data"
        :height="tableHeight"
        highlight-current-row
        :default-sort="{prop: 'orderIndex', order: 'descending'}"
      >
        <el-table-column align="center" width="100">
          <template slot="header">
            <span
              style="
                                font-family: Microsoft YaHei;
                                font-size: 14px;
                                font-weight: 700;
                                color: #3c4353;
                            "
              >序号</span
            >
            <i
              class="el-icon-sort"
              title="按序号排列"
              style="
                                cursor: pointer;
                                font-size: 14px;
                                margin-left: 6px;
                            "
              @click="sortData"
            ></i>
          </template>
          <template slot-scope="scope">
            <el-input
              type="number"
              @change="value => checkNumber(scope.$index, scope.row, value)"
              v-model="scope.row.orderIndex"
            ></el-input>
          </template>
        </el-table-column>
        <el-table-column
          label="字段名称"
          align="center"
          prop="fieldName"
          show-overflow-tooltip
        ></el-table-column>
        <el-table-column
          label="字段注释"
          align="center"
          show-overflow-tooltip
          prop="fieldComments"
        >
          <template slot-scope="scope">
            <el-tooltip
              class="item"
              effect="dark"
              :content="scope.row.fieldComments"
              placement="top"
              v-if="
                scope.row.fieldComments &&
                  scope.row.fieldComments.length >= 12 &&
                  type == 'export'
              "
            >
              <el-input
                v-model="scope.row.fieldComments"
                placeholder="请输入内容"
                :maxlength="50"
              ></el-input>
            </el-tooltip>
            <el-input
              v-if="
                (!scope.row.fieldComments ||
                  scope.row.fieldComments.length < 12) &&
                  type == 'export'
              "
              v-model="scope.row.fieldComments"
              placeholder="请输入内容"
              :maxlength="50"
            ></el-input>
            <span v-if="type == 'import'">{{ scope.row.fieldComments }}</span>
          </template>
        </el-table-column>
        <el-table-column
          label="字段显示值"
          align="center"
          v-if="type == 'export'"
          width="120"
        >
          <template slot-scope="scope">
            <el-select
              v-model="scope.row.fieldViewType"
              placeholder=""
              @change="val => changeViewType(scope.$index, scope.row)"
            >
              <el-option label="原始值" :value="1"></el-option>
              <el-option label="格式化值" :value="2"></el-option>
            </el-select>
          </template>
        </el-table-column>
        <el-table-column
          label="格式化数据"
          align="center"
          v-if="type == 'export'"
        >
          <template slot-scope="scope">
            <el-tooltip
              class="item"
              effect="dark"
              :content="scope.row.fieldDataJson"
              placement="top"
              v-if="scope.row.fieldDataJson && scope.row.fieldViewType == 2"
            >
              <el-input
                readonly
                v-model="scope.row.fieldDataJson"
                placeholder="请输入内容"
              >
                <el-button
                  slot="append"
                  icon="el-icon-setting"
                  @click="openSetJson(scope)"
                ></el-button
              ></el-input>
            </el-tooltip>
            <el-input
              readonly
              v-if="!scope.row.fieldDataJson && scope.row.fieldViewType == 2"
              v-model="scope.row.fieldDataJson"
              placeholder="请输入内容"
              ><el-button
                slot="append"
                icon="el-icon-setting"
                @click="openSetJson(scope)"
              ></el-button
            ></el-input>
          </template>
        </el-table-column>
        <el-table-column label="操作" align="center" width="140">
          <template slot-scope="scope">
            <el-button
              circle
              plain
              type="primary"
              icon="el-icon-top"
              @click="handleUp(scope.row, scope.$index)"
            ></el-button>
            <el-button
              circle
              plain
              type="primary"
              icon="el-icon-bottom"
              @click="handleDown(scope.row, scope.$index)"
            ></el-button>
            <el-popconfirm
              style="margin-left: 10px"
              confirm-button-text="确定"
              cancel-button-text="取消"
              icon="el-icon-info"
              icon-color="red"
              title="确定删除吗？"
              @onConfirm="handleDelFields(scope.row)"
            >
              <el-button
                slot="reference"
                circle
                type="danger"
                icon="el-icon-delete"
              ></el-button>
            </el-popconfirm>
          </template>
        </el-table-column>
      </el-table>
      <span slot="footer" class="dialog-footer">
        <el-button @click="closeDialog">取 消</el-button>
        <el-button type="primary" @click="handleSave">
          保存配置
        </el-button>
      </span>
    </el-dialog>
    <AddFields
      ref="AddFields"
      @addFiedls="handleAddFields"
      :type="type"
      :bizCode="bizCode"
      :dataBaseOptions="dataBaseOptions"
      :originAPIOptions="originAPIOptions"
    ></AddFields>
    <FormatJson ref="setJson" @getJson="handleGetJSon"></FormatJson>
  </div>
</template>

<script>
import utils from '@/hotent-ui-util'
import portal from '@/api/portal'
import AddFields from '@/components/ImportExportData/AddFields'
import FormatJson from '@/components/ImportExportData/FormatJson'
export default {
  name: 'DataTemplateSetting',
  components: {AddFields, FormatJson},
  props: {
    // 页面组件别名
    bizCode: {
      type: String,
      default: '',
      required: true
    },
    // 模板文件名称
    tempFiles: {
      type: String,
      default: '',
      required: true
    },
    type: {
      type: String,
      default: 'import',
      required: true,
      validator: type => {
        if (type == 'import' || 'export') {
          return true
        } else {
          return false
        }
      }
    },
    originAPIOptions: {
      type: Object,
      default: () => {},
      required: true
    },
    dataBaseOptions: {
      type: Object,
      default: () => {},
      required: true
    }
  },
  computed: {
    title() {
      if (this.type == 'import') {
        return '导入模板配置'
      } else {
        return '导出模板配置'
      }
    }
  },
  data() {
    return {
      dialogShow: false,
      tableHeight: 300,
      tempId: '',
      tempData: {}, // 模板基础数据
      data: [],
      loading: false
    }
  },
  mounted() {
    this.calcTableHeight()
    this.$root.$on('resize', () => {
      this.calcTableHeight(500)
    })
  },
  methods: {
    changeViewType(index, row) {
      let tempRow = utils.deepClone(row)
      tempRow.fieldDataJson = ''
      this.data.splice(index, 1, tempRow)
    },
    checkNumber(index, row, num) {
      let number
      if (!num) {
        number = 0
      } else {
        number = parseInt(num)
        if (number < 0) {
          number = 0
        }
      }
      row.orderIndex = number
      this.data.splice(index, 1, row)
    },
    sortData() {
      this.data.sort((a, b) => {
        const nameA = a.orderIndex
        const nameB = b.orderIndex
        if (nameA < nameB) {
          return -1
        }
        if (nameA > nameB) {
          return 1
        }
        return 0
      })
    },
    kvJson(json) {
      let kvJson = {}
      if (json) {
        let temp = JSON.parse(json)
        temp.forEach(item => {
          kvJson[item.value] = item.label
        })
        kvJson = JSON.stringify(kvJson)
      }
      return kvJson
    },
    // 保存配置
    handleSave() {
      if (!this.data.length) {
        this.$message.warning('请配置模板！')
        return
      }
      let dataParams = utils.deepClone(this.data)
      dataParams.forEach((item, index) => {
        if (this.tempId) {
          item.tempId = this.tempId
        }

        item.type = this.type == 'import' ? 2 : 1
        item.fieldType = 1
        delete item.dataType
        delete item.fieldDesc
        delete item.key
        delete item.tableName
        delete item.columnComment
        delete item.columnName
      })
      let data = {
        excelTemp: {
          id: this.tempData.id,
          tempFiles: this.tempFiles,
          bizCode: this.bizCode,
          dbDataBase: this.dataBaseOptions.tableSchema,
          dbSourceId: this.dataBaseOptions.dataBaseId,
          dbTable: this.dataBaseOptions.tableName,
          type: this.type == 'import' ? 2 : this.type == 'export' ? 1 : 'null' // 类型不对报错 类型（1：导出 2：导入）
        },
        fields: dataParams
      }
      portal.saveTemplate(data).then(res => {
        console.log(res)
        if (res.state) {
          this.$message.success('保存成功')
          this.closeDialog()
          this.$emit('reload')
        }
      })
    },
    // 返回json赋值
    handleGetJSon(json, scope) {
      let tempRow = utils.deepClone(scope.row)
      tempRow.fieldDataJson = json
      this.data.splice(scope.$index, 1, tempRow)
    },
    // 编辑json
    openSetJson(scope) {
      this.$refs.setJson.openDialog(scope)
    },
    // 打开配置
    openDialog(tempId) {
      this.tempId = tempId
      this.dialogShow = true
      if (tempId) {
        this.loadTempData(tempId)
      }

      // 取消拖拽排序
      // this.$nextTick(() => {
      //     this.setDraggable()
      // })
    },
    // 查询已有配置
    loadTempData(id) {
      this.loading = true
      portal.loadTempData(id).then(res => {
        this.tempData = res.excelTemp
        this.data = this.formatData(res.fields)
        this.loading = false
      })
    },
    // 格式化回填数据
    formatData(data) {
      data.forEach((item, index) => {
        item.key = index
        item.fieldViewType = parseInt(item.fieldViewType)
      })
      return data
    },
    // 关闭页面重置数据
    closeDialog() {
      this.data = []
      this.dialogShow = false
    },
    // 打开添加字段弹窗
    openAddFieldsDialog() {
      this.$refs.AddFields.openDialog()
    },
    // 对象数组去重
    unique(arr) {
      const res = new Map()
      return arr.filter(
        arr => !res.has(arr.fieldName) && res.set(arr.fieldName, 1)
      )
    },
    // 添加字段
    handleAddFields(row) {
      const addFields = utils.deepClone(row)
      const originFields = utils.deepClone(this.data)
      let newTarget = originFields.concat(addFields)
      if (this.type == 'export') {
        newTarget.sort((a, b) => {
          const nameA = a.fieldName.toUpperCase()
          const nameB = b.fieldName.toUpperCase()
          if (nameA < nameB) {
            return -1
          }
          if (nameA > nameB) {
            return 1
          }
          return 0
        })
      } else if (this.type == 'import') {
        newTarget = this.unique(newTarget)
      }
      newTarget.forEach((item, index) => {
        item.key = index
        item.fieldViewType = 1
        item.orderIndex = index
      })
      this.data = newTarget
      console.log(this.data, 'this.data')
      this.$forceUpdate()
    },
    handleUp(row, index) {
      if (index !== 0) {
        let targetItem = row // 当前Item
        let upItem = this.data[index - 1] // 前一个Item
        let targetIndex = this.data[index].orderIndex // 当前ItemIndex
        let upIndex = this.data[index - 1].orderIndex // 前一个ItemIndex
        // 交换orderIndex
        targetItem.orderIndex = upIndex
        upItem.orderIndex = targetIndex
        this.data.splice(index - 1, 2, targetItem, upItem)
      } else {
        this.$message.warning('已经处于置顶，无法上移')
      }
    },
    handleDown(row, index) {
      if (index !== this.data.length - 1) {
        let targetItem = row // 当前Item
        let downItem = this.data[index + 1] // 前一个Item
        let targetIndex = this.data[index].orderIndex // 当前ItemIndex
        let downIndex = this.data[index + 1].orderIndex // 前一个ItemIndex
        // 交换orderIndex
        targetItem.orderIndex = downIndex
        downItem.orderIndex = targetIndex
        this.data.splice(index, 2, downItem, targetItem)
      } else {
        this.$message.warning('已经处于置底，无法下移')
      }
    },
    // 删除字段
    handleDelFields(row) {
      if (row.id) {
        portal.DeleteExportFields(row.id).then(res => {
          if (res.state) {
            let data = utils.deepClone(this.data)
            let target = data.filter(item => item.key != row.key)
            this.data = target
            this.$message.success('删除成功')
          }
        })
      } else {
        let data = utils.deepClone(this.data)
        let target = data.filter(item => item.key != row.key)
        this.data = target
        this.$message.success('删除成功')
      }
    },
    debounce(fn, delay) {
      clearTimeout(this.timer)
      this.timer = setTimeout(function() {
        fn()
      }, delay)
    },
    // 设置表格拖拽
    setDraggable() {
      const table = this.$refs.DTTable
      const $data = table.data
      const tbody = table.$el.querySelector('.el-table__body-wrapper tbody')
      const $this = this
      const trArr = tbody.querySelectorAll('tr')
      let dragStartY = 0
      if (trArr) {
        trArr.forEach((item, index) => {
          item.setAttribute('draggable', true)
          item.setAttribute('data-index', index)
        })
      }
      // 开始拖拽
      function dragstart(e) {
        console.log(e, 'dfsf')
        $this.debounce(() => {
          dragStartY = e.y
        }, 50)
      }
      // 结束拖拽
      function dragend(e) {
        if (!e.target) return
        const index = Number(e.target.dataset.index, 10)
        const trHeight = e.target.offsetHeight || 45
        $this.debounce(async () => {
          const dVal = e.y - dragStartY
          const absVal = Math.abs(dVal)
          let step = 0
          if (absVal >= trHeight) {
            if (dVal > 0) {
              step = Math.floor(dVal / trHeight)
              if (step >= $data.length - index) {
                step = $data.length - index - 1
              }
            } else {
              step = Math.ceil(dVal / trHeight)
              if (Math.abs(step) > index) {
                step = index * -1
              }
            }
            if (index === 0 && step <= 0) {
              return
            }
            if (index === $data.length - 1 && step >= 0) {
              return
            }
            // const params = {
            //     id: $data[index].id,
            //     step: step * -1,
            // }
            const params = {
              index,
              step: step * -1
            }
            console.log(params, 'params')
            $this.changeSort(params)
            // $this.loading = true
            // // 后端接口
            // await $this.$api.url.setContentSort(params)
            // // 重新获取数据
            // $this.reloadData()
          }
        }, 50)
      }
      tbody.addEventListener('dragstart', dragstart)
      tbody.addEventListener('dragend', dragend)
    },
    // 拖拽结束重新排序
    changeSort(params) {
      let data = utils.deepClone(this.data)
      const targetIndex = params.index - params.step
      let targetItem = data.splice(params.index, 1)
      data.splice(targetIndex, 0, targetItem[0])
      this.data = data
      this.$forceUpdate()
    },
    // 动态计算表格的高度，自适应当前容器
    calcTableHeight(delay) {
      setTimeout(() => {
        this.tableHeight = document.documentElement.clientHeight * 0.9 - 200
      }, delay || 0)
    }
  }
}
</script>

<style lang="scss" scoped>
.sort-icon {
  font-size: 18px;
  vertical-align: middle;
}
.dt-button-group {
  margin-bottom: 20px;
  cursor: pointer;
}
.dt-table {
  ::v-deep .el-input--small .el-input__inner {
    border-radius: 4px;
  }
}
</style>
