<template>
  <el-row>
    <el-form-item label="控件标题">
      <el-input v-model="activeData.__config__.label" placeholder="请输入控件标题" />
    </el-form-item>
    <el-form-item label="占位提示">
      <el-input v-model="activeData.placeholder" placeholder="请输入占位提示" />
    </el-form-item>
    <template v-if="!activeData.__config__.isSubTable">
      <el-form-item label="控件栅格">
        <el-slider v-model="activeData.__config__.span" :max="24" :min="6" show-stops :step="2" show-tooltip />
      </el-form-item>
      <el-form-item label="标题宽度">
        <el-input-number v-model="activeData.__config__.labelWidth" placeholder="标题宽度" :min="0" :precision="0" controls-position="right" />
      </el-form-item>
    </template>
    <el-form-item label="控件宽度" v-if="activeData.__config__.isSubTable">
      <el-input-number v-model="activeData.__config__.columnWidth" placeholder="控件宽度" :min="0" :precision="0" controls-position="right" />
    </el-form-item>
    <el-form-item label="默认值">
      <el-select v-model="activeData.__config__.defaultValue" placeholder="选择默认值" clearable :multiple="activeData.multiple" filterable>
        <el-option v-for="(item, i) in activeData.__slot__.options" :key="i" :label="item[activeData.__config__.props.label]" :value="item[activeData.__config__.props.value]"> </el-option>
      </el-select>
    </el-form-item>
    <el-divider>选项</el-divider>
    <!--    <el-form-item label="关联级联" v-if="activeData.__config__.dataType === 'static'">-->
    <!--      <el-select v-model="activeData.__config__.relationSelectId" placeholder="选择关联级联组件" clearable filterable>-->
    <!--        <el-option v-for="(item, i) in getrelationSelectList(activeData.__config__)" :key="i" :label="item.__config__.label" :value="item.__vModel__"> </el-option>-->
    <!--      </el-select>-->
    <!--    </el-form-item>-->
    <el-form-item label="" label-width="40px">
      <el-radio-group v-model="activeData.__config__.dataType" size="small" style="text-align: center" @change="dataTypeChange">
        <el-radio-button label="static">静态数据</el-radio-button>
        <el-radio-button label="dictionary">数据字典</el-radio-button>
        <el-radio-button label="dynamic">API数据</el-radio-button>
      </el-radio-group>
    </el-form-item>
    <template v-if="activeData.__config__.dataType === 'static'">
      <draggable :list="activeData.__slot__.options" :animation="340" group="selectItem" handle=".option-drag">
        <div v-for="(item, index) in activeData.__slot__.options" :key="index" class="select-item">
          <div class="select-line-icon option-drag">
            <i class="el-icon-s-operation" />
          </div>
          <el-input v-model="item.fullName" placeholder="选项名(value)" size="small" @input="optionsChange($event, item)" />
          <el-input v-model="item.id" placeholder="选项值(key)" size="small" @input="optionsChange($event, item)" />
          <el-input v-if="activeData.__config__.relationSelectId" v-model="item.relation" placeholder="关联关键词" size="small" />
          <div class="close-btn select-line-icon" @click="activeData.__slot__.options.splice(index, 1)">
            <i class="el-icon-remove-outline" />
          </div>
        </div>
      </draggable>
      <div style="margin-left: 29px">
        <el-button style="padding-bottom: 0" icon="el-icon-circle-plus-outline" type="text" @click="addSelectItem"> 添加选项 </el-button>
      </div>
    </template>
    <!--    <JNPF-TreeSelect :options="treeData" v-model="activeData.__config__.dictionaryType"-->
    <!--      placeholder="选择数据字典" lastLevel v-if="activeData.__config__.dataType==='dictionary'" clearable>-->
    <!--    </JNPF-TreeSelect>-->
    <el-select @change="wallpaperInput" placeholder="选择数据字典" v-model="activeData.__config__.dictionaryType" v-if="activeData.__config__.dataType === 'dictionary'">
      <el-option v-for="(item, i) of treeData" :key="i" :value="item.id" :label="item.keyCode"></el-option>
    </el-select>
    <template v-if="activeData.__config__.dataType === 'dynamic'">
      <el-form-item label="API数据">
        <el-cascader
          :options="dataInterfaceSelector"
          v-model="activeData.__config__.propsUrl"
          placeholder="请选择API数据"
          :filter-method="apiFilterMethod"
          :props="{ expandTrigger: 'hover', emitPath: false }"
          :show-all-levels="false"
          @change="propsUrlChange"
          clearable
          filterable
        >
        </el-cascader>
      </el-form-item>
      <el-divider v-if="activeData.__config__.ApiParams && activeData.__config__.ApiParams.length">API输入参数设置</el-divider>
      <el-form-item class="varFormItem" v-for="(param, i) of activeData.__config__.ApiParams" :key="i" :label="param.name + ' ' + param.key">
        <el-cascader v-model="param.varType" :options="varTypeList" @visible-change="allVarListChange"></el-cascader>
        <el-input v-if="param.varType == 1 && param.datatype === 'string'" v-model="param.def"></el-input>
        <el-input v-if="param.varType == 1 && param.datatype === 'number'" v-model="param.def" type="number"></el-input>
        <el-date-picker v-if="param.varType == 1 && param.datatype === 'date'" v-model="param.def" placeholder="选择日期" type="date" value-format="yyyyMMdd"></el-date-picker>
        <el-date-picker v-if="param.varType == 1 && param.datatype === 'month'" v-model="param.def" placeholder="选择月" type="month" value-format="yyyyMM"></el-date-picker>
        <el-time-picker v-if="param.varType == 1 && param.datatype === 'time'" v-model="param.def" placeholder="选择时间" value-format="HH:mm:ss"></el-time-picker>
        <el-date-picker v-if="param.varType == 1 && param.datatype === 'timestamp'" v-model="param.def" placeholder="选择日期" type="date" value-format="timestamp"></el-date-picker>
        <el-time-picker v-if="param.varType == 1 && param.datatype === 'timestamp'" v-model="param.def" placeholder="选择时间" value-format="timestamp"></el-time-picker>
      </el-form-item>
      <el-divider>API返回值设置</el-divider>
      <el-form-item>
        <template slot="label">
          <span>组件设置:</span>
          <el-tooltip style="cursor: pointer" effect="dark" :content="'当前组件设置，指定API返回值某一项作为key或value'" placement="top">
            <i class="el-icon-question" />
          </el-tooltip>
        </template>
        <el-button size="mini" type="primary" plain @click="previewClick" icon="View">API返回值结构预览</el-button>
      </el-form-item>
      <el-form-item label="key值">
        <el-select placeholder="请选择key值" v-model="activeData.__config__.apiProps.value">
          <el-option v-for="(item, i) of showFields" :key="i" :value="item.columnComments" :label="item.columnName"></el-option>
        </el-select>
      </el-form-item>
      <el-form-item label="value值">
        <el-select placeholder="请选择value值" v-model="activeData.__config__.apiProps.label">
          <el-option v-for="(item, i) of showFields" :key="i" :value="item.columnComments" :label="item.columnName"></el-option>
        </el-select>
      </el-form-item>
      <el-form-item label="副标题">
        <el-select placeholder="请选择副标题" multiple v-model="activeData.__config__.apiProps.fitLabel" @change="fitLabelChange">
          <el-option v-for="(item, i) of showFields" :key="i" :value="item.columnComments" :label="item.columnName"></el-option>
        </el-select>
      </el-form-item>
      <el-form-item v-if="activeData.__config__.apiProps.fitLabel.length" label="标题分隔符">
        <el-input v-model="activeData.__config__.apiProps.labelSeparator" placeholder="请输入标题分隔符" />
      </el-form-item>
      <template v-if="activeData.__config__.ApiReturn && activeData.__config__.ApiReturn.length">
        <el-form-item>
          <template slot="label">
            <span>变量设置:</span>
            <el-tooltip style="cursor: pointer" effect="dark" :content="'当前页面变量设置，从API返回值结构预览中选择一或多个类作为变量'" placement="top">
              <i class="el-icon-question" />
            </el-tooltip>
          </template>
        </el-form-item>
        <el-table :data="activeData.__config__.ApiReturn" style="width: 100%">
          <el-table-column prop="keyName" label="API返回值"></el-table-column>
          <el-table-column label="页面变量名">
            <template slot-scope="scope">
              <el-input @input="varNamefitlte(scope.row, $event)" v-model="scope.row.varName" placeholder="请输入页面变量名" />
              <div v-if="varNamefitlteclass(scope.row, scope.row.varName)" style="color: red">变量名重复 重新输入</div>
            </template>
          </el-table-column>
          <el-table-column label="操作" width="50">
            <template slot-scope="scope">
              <div class="close-btn select-line-icon" style="cursor: pointer" @click="activeData.__config__.ApiReturn.splice(scope.$index, 1)">
                <i class="el-icon-delete" />
              </div>
            </template>
          </el-table-column>
        </el-table>
      </template>
    </template>
    <el-divider />
    <!-- <el-form-item label="显示标签">
      <el-switch v-model="activeData.__config__.showLabel" />
    </el-form-item> -->
    <el-form-item>
      <template slot="label">
        <span>应用变量</span>
        <el-tooltip style="cursor: pointer" effect="dark" :content="'将当前组件应用为表单内全局变量'" placement="top">
          <i class="el-icon-question" />
        </el-tooltip>
      </template>
      <el-switch v-model="activeData.allVar" />
    </el-form-item>
    <el-form-item label="能否清空">
      <el-switch v-model="activeData.clearable" />
    </el-form-item>
    <el-form-item label="是否禁用">
      <el-switch v-model="activeData.disabled" />
    </el-form-item>
    <el-form-item label="能否搜索">
      <el-switch v-model="activeData.filterable" />
    </el-form-item>
    <el-form-item label="是否多选">
      <el-switch v-model="activeData.multiple" @change="multipleChange" />
    </el-form-item>
    <el-form-item label="是否隐藏">
      <el-switch v-model="activeData.displayNone" />
    </el-form-item>
    <el-form-item label="是否必填">
      <el-switch v-model="activeData.__config__.required" />
    </el-form-item>
    <el-dialog :visible.sync="previewShow" title="API数据结构预览" width="800px" append-to-body class="source-http-preview">
      <el-table :data="previewArr" border row-key="path" default-expand-all>
        <el-table-column label="结构">
          <template #default="scope">
            {{ scope.row.key }}
          </template>
        </el-table-column>
        <el-table-column label="类型" width="100px" align="center">
          <template #default="scope">
            {{ scope.row.type }}
          </template>
        </el-table-column>
        <el-table-column label="jsonpath">
          <template #default="scope">
            {{ scope.row.path }}
          </template>
        </el-table-column>
        <el-table-column label="操作" width="140px" align="center">
          <template #default="scope">
            <el-button v-if="scope.row.type === 'array'" size="small" type="primary" plain @click="getAllPath(scope.row)"> 使用全部子项 </el-button>
            <el-button v-if="scope.row.type !== 'array' && scope.row.type !== 'object'" size="small" type="primary" plain @click="getPath(scope.row)"> 使用 </el-button>
          </template>
        </el-table-column>
      </el-table>
    </el-dialog>
  </el-row>
</template>
<script>
import comMixin from './mixin'
import draggable from 'vuedraggable'
import { dataapicategoryList, dataapiDetail, dataapiList } from '@/api/systemData/dataInterface'
import { dictDetail, dictList } from '@/api/newbi/dict'
import { clearChildren, countTreeOptions, getAPIData } from '@/components/Dataset-filter/util'
import { getparamsys, paramList } from '@/api/newbi/globalParams'
import { openurl } from '@/components/Dataset-filter/report'
import { param } from '@/components/Dataset-filter/config'
import { loopActiveTabelList, loopRelationList, loopRelationTabelList } from '@/utils'
export default {
  props: ['activeData', 'drawList'],
  mixins: [comMixin],
  components: { draggable },
  data() {
    return {
      treeData: [],
      dataInterfaceSelector: [],
      allVarList: [], //全局变量
      sysVarList: [], //系统变量
      apiVarList: [], //api返回值变量
      varTypeList: [], //变量合计
      previewShow: false,
      previewArr: [],
      showFields: [],
      apiJoinName:'',
    }
  },
  created() {
    this.getDictionaryType()
    this.getDataInterfaceSelector()
    if (this.activeData.__config__.dataType === 'dynamic' && this.activeData.__config__.propsUrl) {
      this.propsUrlChange(this.activeData.__config__.propsUrl)
    }
  },
  watch: {
    'activeData.__config__.dictionaryType': function (val) {
      if (!val) {
        this.activeData.__slot__.options = []
        return
      }
      dictDetail({ id: val }).then((res) => {
        // this.activeData.__slot__.options = res.data.data.list
        let content = JSON.parse(res.data.data.content || '[]')
        this.activeData.__slot__.options = content.map((i) => ({ fullName: i.value, id: i.key }))
      })
    }
  },
  methods: {
    previewClick() {
      if (!this.activeData.__config__.propsUrl)
        return this.$message({
          message: '当前未选择API接口，不支持数据预览',
          type: 'warning'
        })
      dataapiDetail(this.activeData.__config__.propsUrl).then((res) => {
        let { apiKey } = res.data.data
        this.apiJoinName = res.data.data.apiName
        let resJson = JSON.parse(res.data.data.note || '{}')
        let formVarObj = {}
        if (resJson.params && resJson.params.length) {
          resJson.params.forEach((i, k) => {
            formVarObj[i.key] = i.def
          })
        }
        openurl(apiKey, { ...param, ...formVarObj }).then((res) => {
          let data = res.data
          try {
            let arr = []
            this.previewShow = true
            this.jsonPath(arr, data, '$')
            this.previewArr = arr
          } catch (e) {
            this.$message({ message: '接口返回数据格式不支持', type: 'warning' })
          }
        })
      })
    },
    getPath(item) {
      this.getAPiPath(item)
    },
    getAllPath(array) {
      array.children.forEach((item) => this.getAPiPath(item))
    },
    getAPiPath({ key }) {
      if (this.activeData.__config__.ApiReturn.find((i) => i.keyName === key)) return
      this.activeData.__config__.ApiReturn.push({ keyName: key, varName: key, apiName:this.apiJoinName })
      this.getAllapiVarList()
      this.varTypeList[3].children = this.apiVarList
    },
    jsonPath(arr, json, basePath) {
      const type = this.validateType(json)
      if (type === 'object') {
        for (let key in json) {
          const item = {
            key,
            path: `${basePath}.${key}`
          }
          const childType = this.validateType(json[key])
          item.type = childType
          if (childType === 'object' || childType === 'array') {
            item.leaf = true
            item.children = []
            this.jsonPath(item.children, json[key], item.path)
          } else {
            item.leaf = false
            item.value = json[key]
          }
          arr.push(item)
        }
      } else if (type === 'array') {
        json = json[0]
        if (json === undefined) return
        for (let key in json) {
          const item = {
            key,
            path: `${basePath}[*].${key}`
          }
          const childType = this.validateType(json[key])
          item.type = childType
          if (childType === 'object' || childType === 'array') {
            item.leaf = true
            item.children = []
            this.jsonPath(item.children, json[key], item.path)
          } else {
            item.leaf = false
            item.value = json[key]
          }
          arr.push(item)
        }
      }
    },
    validateType(val) {
      // 校验JSON数据类型
      const type = typeof val
      if (type === 'object') {
        if (Array.isArray(val)) {
          return 'array'
        } else if (val === null) {
          return 'null'
        } else {
          return 'object'
        }
      } else {
        return type
      }
    },
    varNamefitlte(row, val) {
      if (this.activeData.__config__.ApiReturn.find((i) => i.varName === val && i.keyName !== row.keyName)) {
        this.activeData.varRepeat = true
        return this.$message({
          message: '检测到变量命名重复，请重新输入',
          type: 'warning'
        })
      }
      if (this.apiVarList.find((i) => i.label === val)) {
        this.activeData.varRepeat = true
        return this.$message({
          message: '检测到变量命名重复，请重新输入',
          type: 'warning'
        })
      }
      this.activeData.varRepeat = false
      this.getAllapiVarList()
      this.varTypeList[3].children = this.apiVarList
    },
    varNamefitlteclass(row, val) {
      let flag = false
      if (this.activeData.__config__.ApiReturn.find((i) => i.varName === val && i.keyName !== row.keyName)) {
        flag = true
      }
      if (this.apiVarList.filter((i) => i.label === val).length > 1) {
        flag = true
      }
      return flag
    },
    wallpaperInput() {
      this.$forceUpdate()
    },
    getDictionaryType() {
      // getDictionaryTypeSelector().then(res => {
      //   this.treeData = res.data.data.list
      // })
      dictList({ current: 1, size: 10000 }).then((res) => (this.treeData = res.data.data.records))
    },
    //相同组件切换时 表单内全局变量数据不会及时更新  利用下拉框出现时刷新一下
    allVarListChange(val) {
      if (val) {
        this.getAllVarList()
        this.getAllapiVarList()
        this.varTypeList[2].children = this.allVarList
        this.varTypeList[3].children = this.apiVarList
      }
    },
    getDataInterfaceSelector() {
      this.getAllVarList()
      this.getAllapiVarList()
      //获取api列表
      dataapicategoryList().then((res) => {
        let category = res.data.data
        dataapiList({ apiFormal: 1, apiTypes: '1,2' }).then((res) => {
          let list = res.data.data
          this.dataInterfaceSelector = category
            .map((i) => ({
              label: i.categoryName,
              value: i.id,
              children: list.filter((j) => j.categoryId === i.id).map((k) => ({ label: k.apiName, value: k.id, key: k.apiKey }))
            }))
            .filter((i) => i.children.length)
        })
        this.getSysparamList()
      })
    },
    getSysparamList() {
      //获取全局系统变量
      paramList({ paramType: 'SYSTEM' }).then((res) => {
        let arr = res.data.data.records
        getparamsys({ dateFormat: 'yyyy_MM_dd' }).then((r) => {
          let sysVarValue = r.data.data
          if (sysVarValue) {
            this.sysVarList = arr
              .map((i) => {
                return {
                  label: i.paramName,
                  value: sysVarValue[i.paramKey] || null
                }
              })
              .filter((l) => l !== undefined)
          }
        })
        this.varTypeList = [
          { value: 1, label: '默认值' },
          { value: 2, label: '系统全局变量', children: this.sysVarList || [] },
          { value: 3, label: '表单全局变量', children: this.allVarList || [] },
          { value: 4, label: 'api全局变量', children: this.apiVarList || [] }
        ]
      })
    },
    addSelectItem() {
      this.activeData.__slot__.options.push({
        relation: '',
        fullName: '',
        id: ''
      })
      this.$nextTick(() => {
        this.$forceUpdate()
      })
    },
    //自定义选项时 值发生改变
    optionsChange(e, val) {
      // this.$forceUpdate()
      // val.id = e
    },
    getrelationSelectList(scheme) {
      let selectList = []
      //如果是子表单内组件
      if (scheme.relationTable) {
        let arr = this.drawList.filter((o) => o.__config__.jnpfKey === 'table' && o.__config__.tableName === scheme.relationTable)
        if (!arr.length) return
        selectList = arr[0].__config__.children
          .map((i) => {
            if (i.__config__.jnpfKey === 'select' && Number(i.__vModel__) !== Number(this.activeData.__vModel__)) {
              return i
            }
          })
          .filter((l) => l !== undefined)
      } else {
        selectList = this.drawList
          .map((i) => {
            if (i.__config__.jnpfKey === 'select' && Number(i.__vModel__) !== Number(this.activeData.__vModel__)) {
              return i
            }
          })
          .filter((l) => l !== undefined)
      }
      return selectList
    },
    getAllVarList() {
      //获取表单内变量
      let mapList = this.activeData.__config__.relationTable ? loopActiveTabelList(this.drawList, this.activeData.__config__.relationTable) : loopRelationList(this.drawList)
      this.allVarList = mapList
        .map((o) => {
          if (o.allVar) {
            return {
              label: o.__config__.label,
              value: o.__vModel__
            }
          }
        })
        .filter((l) => l !== undefined)
    },
    getAllapiVarList() {
      //获取API返回变量
      this.apiVarList = []
      let mapList = this.activeData.__config__.relationTable ? loopActiveTabelList(this.drawList, this.activeData.__config__.relationTable) : loopRelationList(this.drawList)
      mapList.forEach((item, key) => {
        let config = item.__config__
        if (config.ApiReturn && config.ApiReturn.length) {
          let list = config.ApiReturn.map((o) => {
            return {
              label: o.varName,
              value: o.varName
            }
          }).filter((l) => l !== undefined)
          this.apiVarList = [...this.apiVarList, ...list]
        }
      })
    },
    dataTypeChange(val) {
      this.activeData.__config__.defaultValue = this.activeData.multiple ? [] : ''
      // this.activeData.__slot__.options = []
      this.activeData.__config__.props.value = 'id'
      this.activeData.__config__.props.label = 'fullName'
      if (val === 'static') {
        this.activeData.__config__.dictionaryType = ''
        this.activeData.__config__.propsUrl = ''
        this.activeData.__config__.ApiParams = []
        this.activeData.__slot__.options = []
      }
      if (val === 'dynamic') {
        this.activeData.__config__.dictionaryType = ''
      }
      if (val === 'dictionary') {
        this.activeData.__config__.propsUrl = ''
        this.activeData.__config__.ApiParams = []
      }
      this.$nextTick(() => {
        this.$forceUpdate()
      })
    },
    multipleChange(val) {
      this.$set(this.activeData.__config__, 'defaultValue', val ? [] : '')
    },
    dictionaryTypeChange() {
      this.activeData.__config__.defaultValue = this.activeData.multiple ? [] : ''
    },
    apiFilterMethod(node, keyword) {
      let { label, key } = node.data
      keyword = keyword.toLowerCase()
      return label.includes(keyword) || key.toLowerCase().includes(keyword)
    },
    fitLabelChange() {
      if (!this.activeData.__config__.apiProps.fitLabel.length) {
        this.activeData.__config__.apiProps.labelSeparator = ''
      }
    },
    propsUrlChange(val) {
      if (!val) {
        this.activeData.__slot__.options = []
        return
      }
      // this.activeData.__config__.ApiParams = []
      // this.activeData.__config__.apiProps = {label: '',value: ''}
      this.activeData.__config__.defaultValue = this.activeData.multiple ? [] : ''
      //获取api信息
      dataapiDetail(val).then((res) => {
        //获取api值
        getAPIData(this.activeData.__slot__, val, [], [], '', this.activeData.__config__.apiProps).then((res) => {
          this.$set(this.activeData.__slot__, 'options', res)
        })
        let resJson = JSON.parse(res.data.data.note || '{}')
        this.showFields = resJson.showFields || []
        if (resJson.params && resJson.params.length) {
          //添加变量类型 1：默认 2：全局系统变量 3：表单内全局变量
          if (!this.activeData.__config__.ApiParams.length) {
            resJson.params.forEach((i, k) => [Object.assign(i, { varType: [1] })])
            this.activeData.__config__.ApiParams = resJson.params
          } else {
            let APIKeylist = resJson.params.map((i) => {
              return i.key
            })
            let paramsList = this.activeData.__config__.ApiParams.filter((l) => APIKeylist.includes(l.key))
            paramsList.forEach((i, k) => {
              if (!i.varType) {
                Object.assign(i, { varType: [1] })
              }
            })
            this.activeData.__config__.ApiParams = paramsList
          }
        } else {
          this.activeData.__config__.ApiParams = []
        }
      })
    }
  }
}
</script>
<style lang="scss">
.select-item {
  display: flex;
  border: 1px dashed #fff;
  box-sizing: border-box;
  & .close-btn {
    cursor: pointer;
    color: #f56c6c;
  }
  & .el-input + .el-input {
    margin-left: 4px;
  }
}
.select-item + .select-item {
  margin-top: 4px;
}
.select-item.sortable-chosen {
  border: 1px dashed #409eff;
}
.select-line-icon {
  line-height: 32px;
  font-size: 22px;
  padding: 0 4px;
  color: #777;
}
.option-drag {
  cursor: move;
}
.varFormItem .el-form-item__content {
  display: flex;
}
.apiItem .el-divider__text.is-center {
  width: 280px;
  span {
    margin-right: 6px;
  }
}
</style>
