<template>
  <div>
    <template v-if="formData.popupType === 'general'">
      <vxe-modal
        :title="detailType ? fullName + '详情' : !dataForm.id ? fullName + '新建' : fullName + '编辑'"
        :close-on-click-modal="false"
        v-model="visible"
        lock-scroll
        show-zoom
        show-footer
        transfer
        resize
        height="90%"
        :width="formData.generalWidth"
        :id="'c' + key"
      >
        <!--        页签-->
        <div v-if="detailType === 'detail' && tabList.length" :class="[tabListActiveIndex === primaryFullName ? activeClass : '']">
          <el-menu :default-active="tabListActiveIndex" class="el-menu-demo" mode="horizontal" @select="onTabListSelect">
            <el-menu-item :index="primaryFullName">{{ primaryFullName }}</el-menu-item>
            <el-menu-item :index="item.tabFormId" v-for="(item, i) in tabList" :key="item.id">{{ item.tabName }}</el-menu-item>
          </el-menu>
        </div>
        <div v-if="tabListActiveIndex !== primaryFullName && tabConfig" style="height: 90%">
          <List ref="primaryList" v-if="tabConfig" :config="tabConfig" :modelId="tabModelId" :tabSearch="tabRequst" :isPreview="true" v-show="true" :isComponent="true" :key="tabModelId"></List>
        </div>
        <parser
          :association-relation="associationRelation"
          :detail-type="detailType"
          :form-conf="formData"
          :primary-row-obj="primaryRowObj"
          :relation-conf="relationConf"
          :systemBtns="systemBtns"
          :idKey="idKey"
          @submit="sumbitForm"
          :key="key"
          ref="dynamicForm"
          @relationModal="relationModalClick"
          @relationModalLodig="relationLoadingChange"
          v-loading="relationLoading"
          v-if="!loading && tabListActiveIndex === primaryFullName"
          :model-id="modelId"
        />
        <span slot="footer" class="dialog-footer" v-if="detailType !== 'detail'">
          <template v-if="dataForm.id">
            <template v-for="(item, i) in buttons">
              <el-button type="primary" :icon="item.icon" @click="customBtnsHandel(item)">{{ item.label }}</el-button>
            </template>
          </template>
          <el-button @click="visible = false">{{ formData.cancelButtonText || '取 消' }}</el-button>
          <el-button type="primary" @click="dataFormSubmit()" :loading="btnLoading"> {{ formData.confirmButtonText || '确 定' }}</el-button>
        </span>
      </vxe-modal>
      <inputForm v-show="formVisible" ref="relationForm" />
    </template>
    <template v-if="formData.popupType === 'fullScreen'">
      <transition name="el-zoom-in-center">
        <div class="JNPF-preview-main">
          <div class="JNPF-common-page-header">
            <el-page-header @back="goBack" :content="detailType ? '详情' : !dataForm.id ? '新建' : '编辑'" />
            <div class="options" v-if="detailType !== 'detail'">
              <el-button type="primary" @click="dataFormSubmit()" :loading="btnLoading"> {{ formData.confirmButtonText || '确 定' }}</el-button>
              <el-button @click="goBack">{{ formData.cancelButtonText || '取 消' }}</el-button>
            </div>
          </div>
          <div class="dynamic-form-main" :style="{ margin: '0 auto', width: formData.fullScreenWidth }">
            <parser :form-conf="formData" :relation-conf="relationConf" :idKey="idKey" @submit="sumbitForm" :key="key" ref="dynamicForm" v-if="!loading" />
          </div>
        </div>
      </transition>
    </template>
  </div>
</template>

<script>
import { customTabList, executeCustomButton, getConfigData, NewCreateModel, NewListupdateModel } from '@/api/onlineDev/visualDev'
import Parser from '@/components/Generator/parser/Parser'
import { useDateList } from '@/components/Generator/generator/comConfig'
import { deepClone } from '@/utils'
import { inputComponents } from '@/components/Generator/generator/config'
import moment from 'moment'

export default {
  name: 'inputForm',
  components: { Parser, List: () => import('../list') },
  props: ['relationData', 'buttons', 'systemBtns'],
  data() {
    return {
      visible: false,
      dataForm: {
        id: '',
        data: ''
      },
      modelId: '',
      dbLinkId: '',
      formData: {},
      idKey: '',
      formValue: {},
      key: +new Date(),
      btnLoading: false,
      loading: true,
      isPreview: false,
      useDateList,
      relationConf: [],
      secondaryDbLinkIdList: [],
      primaryRowObj: {},
      primaryTableInfo: {
        data: {}
      },
      detailType: '',
      associationRelation: [],
      relationLoading: false,
      formVisible: false,
      fullName: '',
      primaryFullName: '',
      tabList: [],
      tabListActiveIndex: '',
      tabModelId: '',
      tabConfig: null,
      tabRequst: null,
      formRow: null,
      activeClass: 'primaryActive'
    }
  },
  methods: {
    goBack() {
      this.$emit('refreshDataList')
    },
    getfilterList(arr, u_key) {
      let map = new Map()
      arr.forEach((item, index) => {
        if (!map.has(item[u_key])) {
          map.set(item[u_key], item)
        }
      })
      return [...map.values()]
    },
    init(formData, modelId, id, isPreview, row, idKey, columnDict, dbLinkId, detailType, associationRelation, fullName, viewColumns, viewColumnsFlag) {
      this.columnDict = columnDict
      this.relationConf = this.relationData || []
      this.detailType = detailType
      this.primaryRowObj = {}
      this.fullName = fullName ? fullName + '-' : ''
      this.primaryFullName = fullName ? fullName : ''
      this.tabListActiveIndex = fullName ? fullName : ''
      // //修改时不需要批量
      // if (!id){
      //   let tableChildren = copyFields.fields.filter((item,k)=> item.fatherBoxConfig && item.__fathervModel__)
      //   //将子表数据格式化
      //   if (tableChildren && tableChildren.length){
      //     let NewList = this.getfilterList(tableChildren,'__fathervModel__')
      //     let tabelBox = NewList.map((item,k)=>{
      //       return {
      //         __config__:item.fatherBoxConfig,
      //         __vModel__:item.__fathervModel__,
      //         actionText:item.fatherActionText
      //       }
      //     })
      //     let formList = copyFields.fields.filter((item,k)=> !item.fatherBoxConfig && !item.__fathervModel__)
      //     copyFields.fields = formList.concat(tabelBox)
      //   }
      // }
      this.formData = deepClone(formData)
      if (detailType === 'detail') {
        this.getTabList(modelId)
        this.formData.labelPosition = 'right'
        this.formData.generalWidth = '80%'
      }
      if (row) {
        let primaryRow = deepClone(row)
        this.primaryRowObj = this.getBatchEditJsonData(primaryRow, columnDict)
        // 修改时主表信息
        let filteredData = deepClone(row)
        let primaryTableData = Object.keys(filteredData).reduce((obj, key) => {
          if (!key.startsWith('foreign_')) {
            obj[key] = filteredData[key]
          }
          return obj
        }, {})
        delete primaryTableData.mergeRow
        delete primaryTableData.row
        delete primaryTableData.seq
        delete primaryTableData._X_ROW_KEY
        this.primaryTableInfo.data = JSON.stringify(this.getBatchEditJsonData(primaryTableData, columnDict))
      }
      this.secondaryDbLinkIdList = this.formData.fields
        .map((o) => {
          if (o.__config__.jnpfKey === 'table') {
            return o.__vModel__
          }
        })
        .filter((l) => l !== undefined)
      this.idKey = idKey
      this.modelId = modelId
      this.dbLinkId = dbLinkId
      this.isPreview = isPreview
      this.dataForm.id = id || ''
      this.loading = true
      this.$nextTick(() => {
        if (this.dataForm.id) {
          this.formRow = deepClone(row)
          // getModelInfo(modelId, this.dataForm.id).then(res => {
          //   this.dataForm = res.data.data
          //   if (!this.dataForm.data) return
          //   this.formValue = JSON.parse(this.dataForm.data)
          //   this.fillFormData(this.formData, this.formValue)
          this.associationRelation = associationRelation ? JSON.parse(associationRelation) : []
          this.fillFormData(this.formData, row, columnDict, this.associationRelation, viewColumns, viewColumnsFlag)
          this.$nextTick(() => {
            this.visible = true
            this.loading = false
            this.relationLoading = false
            let oldData = this.formData.fields
              .map((item) => {
                if (item.__config__.jnpfKey !== 'table') {
                  let value = item.__config__.defaultValue
                  let id = item.__vModel__
                  let typeKey = item.__config__.jnpfKey
                  return { value: value, id: id, typeKey: typeKey }
                }
              })
              .filter((l) => l !== undefined)
            oldData.forEach((item, index) => {
              //文本输入框不转
              try {
                if (item.typeKey !== 'comInput') {
                  item.value = JSON.parse(item.value)
                }
              } catch {}
              delete item.typeKey
            })
            this.dataForm.oldData = this.arrTransferObj(oldData, 'id', 'value')
            this.formData.fields.forEach((item) => {
              if (item.__config__.isJoin) {
                delete this.dataForm.oldData[item.__vModel__]
              }
            })
            this.dataForm.oldData = JSON.stringify(this.dataForm.oldData)
          })
          // })
        } else {
          this.dataForm.oldData = null
          this.formValue = {}
          this.visible = true
          this.loading = false
        }
        this.key = +new Date()
      })
    },
    // 获取页签列表
    getTabList(modelId) {
      let params = {
        current: 1,
        size: 1000
      }
      customTabList(modelId, params).then((res) => {
        this.tabList = res.data.data.records
      })
    },
    //整合数据 配合流程进行存储回显数据
    getBatchEditJsonData(row, columnDict) {
      let rows = Object.assign({}, row)
      let jsonData = deepClone(columnDict)
      const obj_ = {}
      // delete jsonData[this.idKey]
      for (let key in jsonData) {
        for (let index in rows) {
          if (jsonData[key] === index) {
            // jsonData[key] = rows[index]
            obj_[key] = rows[index]
          }
        }
      }
      return { ...obj_, ...row }
    },
    /** 数组转对象* @param {Object} e 原始数组 * @param {Object} key 键* @param {Object} val 值*/
    arrTransferObj(e, key, val) {
      // 数组的reduce方法，使数组的obj初始值为{}，将数组中每一个对象所需的值，分别作为对象中的键与值
      return e.reduce((obj, item) => ((obj[item[key]] = item[val]), obj), {})
    },
    fillFormData(form, data, columnDict, associationRelation, viewColumns, viewColumnsFlag) {
      const loop = (list) => {
        for (let i = 0; i < list.length; i++) {
          let item = list[i]
          item.__config__ = { ...item.__config__, ...inputComponents.find((o) => o.__config__.jnpfKey === item.__config__.jnpfKey) }
          if (item.__vModel__) {
            if (item.__config__.isJoin) {
              item.__config__.defaultValue = data[item.__vModel__]
              // 置灰
              item.readonly = true
            } else if (associationRelation.some((o) => o.visualdevTableColumnId == item.__vModel__)) {
              const val = data[columnDict[item.__vModel__]]
              if (val) this.$set(item, 'relationValuePrimaryId', val)
              if (columnDict[item.__vModel__]) {
                let column = columnDict[item.__vModel__] + '_TEXT'
                let columnData = data[column]
                if (columnData) item.__config__.defaultValue = columnData
              }
            } else {
              const val = data[columnDict[item.__vModel__]]
              if (val) item.__config__.defaultValue = val
              if (item.__config__.viewDataType === 'DATETIME') {
                // if (this.useDateList.indexOf(item.__config__.jnpfKey) < 0){
                item.__config__.defaultValue = val ? moment(val).valueOf() : null
                // }
              }
              if (item.__config__ && item.__config__.jnpfKey === 'cascader') {
                try {
                  item.__config__.defaultValue = val ? val.split(item.props.props.separator || ';') : val
                } catch {}
              }
              if (item.__config__ && item.__config__.jnpfKey === 'select') {
                try {
                  item.__config__.defaultValue = val.toString()
                } catch {}
              }
              if (item.__config__ && item.__config__.jnpfKey === 'uploadImg') {
                item.__config__.defaultValue = item.__config__.defaultValue.length ? item.__config__.defaultValue.split(';') : []
              }
              if (item.__config__ && item.__config__.jnpfKey === 'uploadFz') {
                console.log('defaultValue', item.__config__.defaultValue)
                item.__config__.defaultValue = item.__config__.defaultValue.length ? item.__config__.defaultValue.split(';') : []
                // try {
                //   if (item.__config__.defaultValue > 0) {
                //     item.__config__.defaultValue = item.__config__.defaultValue.split(';') || []
                //   } else {
                //     let defaultValue = JSON.parse(item.__config__.defaultValue)
                //     item.__config__.defaultValue = defaultValue.length ? defaultValue : []
                //   }
                // } catch {
                //   if (!item.__config__.defaultValue && item.__config__.defaultValue === 'null' && item.__config__.defaultValue.length <= 0) {
                //     item.__config__.defaultValue = []
                //   } else {
                //     let defaultValue = item.__config__.defaultValue && item.__config__.defaultValue.length ? item.__config__.defaultValue.split(';') : []
                //     if (!defaultValue && !defaultValue.length) return
                //     item.__config__.defaultValue = defaultValue.map((item) => {
                //       let str = 'http://60.190.98.244:9175/system/thumb/' + item
                //       return { name: item, url: str, fileId: str }
                //     })
                //   }
                // }
              }
            }
            //   弹窗内容
            if (viewColumnsFlag && viewColumns?.length) {
              let viewColumnsRow = viewColumns.find((o) => o.id === item.__vModel__)
              if (viewColumnsRow && item.__vModel__ === viewColumnsRow.id) {
                item.displayNone = !viewColumnsRow.isShow
                item.disabled = !viewColumnsRow.isChange
                item.__config__.required = viewColumnsRow.isRequired
              } else {
                item.displayNone = true
              }
            }
          }
          if (item.__config__ && item.__config__.jnpfKey === 'tab' && item.__config__.children && Array.isArray(item.__config__.children)) {
            let tabItem = item.__config__.children
            for (let o = 0; o < tabItem.length; o++) {
              loop(tabItem[o].__config__.children)
            }
          }
          if (item.__config__ && item.__config__.jnpfKey === 'table' && item.__config__.children && Array.isArray(item.__config__.children)) {
            loop(item.__config__.children)
          }
        }
      }
      loop(form.fields)
    },
    getSerialincNumberData(fields, data) {
      let obj = fields.find((o) => o.__config__.jnpfKey === 'serialNumber')
      if (obj) {
        let copySet = deepClone(obj.serialgz)
        copySet.forEach((i, k) => {
          //根据设置生成数据
          if (i.type === 'createTime') {
            this.$set(i, 'chars', moment().format(i.format))
          }
          if (i.type === 'widget') {
            this.$set(i, 'chars', data[i.widgetvModel])
          }
        })
        return { _serialNumber: obj.__vModel__, _serialNumberConfig: copySet }
      } else {
        return null
      }
    },
    //子表整合数据
    flattenedArrayWithKey(foreignObj) {
      const result = []
      for (const key in foreignObj) {
        foreignObj[key].forEach((item) => {
          result.push({ dbLink: key, id: '', oldData: null, data: JSON.stringify(item) })
        })
      }
      return result
    },
    sumbitForm(data) {
      console.log(data)
      if (!data) return
      data = Object.keys(data).reduce((obj, key) => {
        if (!key.startsWith('isOnlyRead_')) {
          obj[key] = data[key]
        }
        return obj
      }, {})
      //获取流水号数据
      this.btnLoading = true
      let params = {}
      //查询是否新增 新增的情况下 查询有没有子表
      // if (!this.dataForm.id){
      //主表数据
      const primaryObj = {}
      //子表数据
      const foreignObj = {}
      this.formData.fields.forEach((item) => {
        if (item.__config__.jnpfKey === 'uploadImg') {
          let val = ''
          if (data[item.__vModel__] && data[item.__vModel__].length) {
            data[item.__vModel__].forEach((item) => {
              // 如果是数字
              if (item > 0) {
                val += item + ';'
              } else if (item.type === 'new') {
                val += item.url + ';'
              }
            })
          }
          // 去掉最后一个分号
          data[item.__vModel__] = val.substring(0, val.length - 1)
        }
        if (item.__config__.jnpfKey === 'uploadFz') {
          let val = ''
          if (data[item.__vModel__] && data[item.__vModel__].length) {
            data[item.__vModel__].forEach((item) => {
              if (item > 0) {
                val += item + ';'
              } else if (item.id) {
                val += item.id + ';'
              }
            })
          }
          // 去掉最后一个分号
          data[item.__vModel__] = val.substring(0, val.length - 1)
        }
        if (item.__config__.isJoin) {
          delete data[item.__vModel__]
        }
      })
      //获取提交数据时 查询存在于子表数据集合的key 将主子表数据区分开
      for (const key in data) {
        if (this.secondaryDbLinkIdList.includes(Number(key)) && Array.isArray(data[key])) {
          foreignObj[key] = data[key]
        } else {
          primaryObj[key] = data[key]
        }
      }
      //获取流水号数据
      let serialincNumberData = this.getSerialincNumberData(this.formData.fields, data)
      console.log(primaryObj)
      //主表整合信息
      let primaryTable = {
        dbLink: this.dbLinkId,
        id: this.dataForm.id ? this.dataForm.id : '',
        oldData: this.dataForm.oldData ? this.dataForm.oldData : null,
        data: JSON.stringify(primaryObj),
        ...serialincNumberData
      }
      //子表整合数据
      let foreignTable = this.flattenedArrayWithKey(foreignObj)
      params = {
        primaryTable: primaryTable,
        foreignTable: foreignTable
      }
      if (this.dataForm.id) {
        params.primaryTableInfo = this.primaryTableInfo
        const find = this.systemBtns.find((o) => o.value === 'edit')
        if (find && find.buttonId) {
          params.buttonId = +find.buttonId
        }
      } else {
        const find = this.systemBtns.find((o) => o.value === 'add')
        if (find && find.buttonId) {
          params.buttonId = +find.buttonId
        }
      }
      // }else {
      //   //主表数据
      //   const primaryObj = {};
      //   //获取提交数据时 查询存在于子表数据集合的key 将主子表数据区分开
      //   for (const key in data) {
      //     if (!this.secondaryDbLinkIdList.includes(Number(key)) && !Array.isArray(data[key])) {
      //       primaryObj[key] = data[key];
      //     }
      //   }
      //   params = [{
      //     data:JSON.stringify(primaryObj),
      //     id:this.dataForm.id,
      //     oldData:this.dataForm.oldData,
      //   }]
      // }
      const formMethod = this.dataForm.id ? NewListupdateModel : NewCreateModel
      formMethod(this.modelId, params, this.dataForm.id, this.dbLinkId)
        .then((res) => {
          this.$message({
            message: res.data.msg,
            type: 'success',
            duration: 1500,
            onClose: () => {
              this.visible = false
              this.btnLoading = false
              let flagInit = this.dataForm.id ? true : false
              this.$emit('refreshDataList', this.dataForm.id, res.data.data)
            }
          })
        })
        .catch(() => {
          this.btnLoading = false
        })
    },
    dataFormSubmit() {
      if (this.isPreview) return this.$message({ message: '功能预览不支持数据保存', type: 'warning' })
      this.$refs.dynamicForm && this.$refs.dynamicForm.submitForm()
    },
    relationLoadingChange(flag) {
      this.relationLoading = flag
    },
    relationModalClick(formData, modelId, id, isPreview, row, idKey, columnDict, dbLinkId, detailType, associationRelation, fullName) {
      this.formVisible = true
      this.relationLoading = false
      this.$nextTick(() => {
        this.$refs.relationForm.init(formData, modelId, id, isPreview, row, idKey, columnDict, dbLinkId, detailType, associationRelation, fullName)
      })
    },
    customBtnsHandel(button) {
      const loading = this.$loading({
        lock: true,
        text: '执行中',
        spinner: 'el-icon-loading',
        background: 'rgba(0, 0, 0, 0.7)'
      })
      const row = this.$refs.dynamicForm.dataForm
      const data = {
        modelId: this.$parent.modelId
      }
      Object.entries(this.$parent.columnDict).forEach((item) => {
        const [key, value] = item
        const field = this.$parent.columnData.cubeList.find((i) => i.id === +key)
        if (field) {
          data[field.columnName] = row[key]
        }
      })
      const param = {
        buttonId: +button.buttonId,
        modelId: this.$parent.modelId,
        data
      }
      executeCustomButton(param)
        .then((res) => {
          this.$message({
            message: res.data.msg,
            type: 'success',
            duration: 1500
          })
          this.refreshTableLayout()
        })
        .catch((err) => {
          this.$message({
            message: err.data.msg,
            type: 'error',
            duration: 1500
          })
        })
        .finally(() => {
          loading.close()
        })
    },
    onTabListSelect(key) {
      this.tabConfig = null
      this.tabListActiveIndex = key
      let find = this.tabList.find((o) => o.tabFormId === key)
      let data = this.formRow ? this.formRow : {}
      if (find) {
        this.tabRequst = {
          cubeColumnId: find.tabFieldId,
          associationColumn: false,
          function: 'eq',
          values: data && String(data[this.columnDict[find.fieldId]]) ? new Array(String(data[this.columnDict[find.fieldId]])) : []
        }
      } else {
        this.tabRequst = null
      }
      if (this.tabListActiveIndex !== this.primaryFullName) {
        this.tabModelId = key
        getConfigData(key).then((res) => {
          if (res.data.code === 200 && res.data.data) {
            this.tabConfig = res.data.data
          }
        })
      }
    }
  },
  beforeCreate() {
    this.$options.components.primaryList = require('../list').default
  }
}
</script>
<style scoped lang="scss">
.primaryActive {
  margin-bottom: 15px;
}
:deep(.vxe-modal--content) {
  overflow: hidden !important;
  overflow-y: auto !important;
}
::v-deep .el-form-item--small .el-form-item__content {
  line-height: 33px;
}
::v-deep .el-input {
  width: 95% !important;
}
::v-deep .el-input-number--small {
  width: 95% !important;
  line-height: 33px;
}
.relationItem {
  right: 5%;
}
::v-deep .el-input-number[data-prepend] {
  --el-input-number-prepend-offset-x: 65px;
  position: relative;
}
::v-deep .el-input-number[data-prepend]::before {
  content: attr(data-prepend);
  height: 91%;
  display: flex;
  align-items: center;
  position: absolute;
  top: 2px;
  left: 0;
  color: #909399;
  background-color: #f5f7fa;
  border: 1px solid #dcdfe6;
  border-top: none;
  border-bottom: none;
  padding: 0 20px;
  z-index: 1;
}
::v-deep .el-input-number[data-prepend] .el-input__inner {
  padding-left: calc(var(--el-input-number-prepend-offset-x) + 12px);
}
::v-deep .el-input-number[data-append] {
  --el-input-number-append-offset-x: 32px;
  position: relative;
}

::v-deep .el-input-number[data-append]::after {
  content: attr(data-append);
  height: 91%;
  display: flex;
  align-items: center;
  position: absolute;
  top: 2px;
  right: var(--el-input-number-append-offset-x);
  color: #909399;
  background-color: #f5f7fa;
  border: 1px solid #dcdfe6;
  border-top: none;
  border-bottom: none;
  padding: 0 20px;
}
::v-deep .el-input-number[data-append] .el-input__inner {
  padding-right: calc(var(--el-input-number-append-offset-x) + 12px);
}
</style>
