<template>
  <!--  单选框-->
  <a-radio-group v-if="type=='radio'" @change="onChange" :value="getValue" :disabled="disabled || readOnly">
    <a-radio v-for="(item, index) in dictOptions" :key="index" :value="item.value" v-if="item.value !== ''">
      <!--      针对风险灯的特殊处理-->
      <span v-html="item.text || item.label"></span>
      <!--      {{ item.text || item.label }}-->
    </a-radio>
  </a-radio-group>
  <!--复选框-->
  <a-checkbox-group v-else-if="type=='checkbox'" @change="onChange" :value="getValue" :disabled="disabled || readOnly">
    <a-checkbox v-for="(item, index) in dictOptions" :key="index" :value="item.value" v-if="item.value !== ''">
      {{ item.text || item.label }}
    </a-checkbox>
  </a-checkbox-group>
  <!--下拉框-->
  <a-select
    :showSearch="showSearch"
    optionFilterProp="children"
    :filter-option="filterOption"
    v-else-if="type=='select'"
    :value="getValue"
    @change="onChange"
    :disabled="disabled || readOnly"
    :mode="mode"
    :placeholder="placeholder"
    :allowClear="allowClear"
    :getPopupContainer="
      triggerNode => {
        return triggerNode.parentNode || document.body;
      }
    "

  >
    <a-select-option v-for="(item,index) in dictOptions" :key="index" :value="item.value"
                     :title="item.text || item.label">
      {{ item.text || item.label }}
    </a-select-option>
  </a-select>
  <!--  树形选择框-->
  <a-tree-select
    treeDefaultExpandAll
    :showSearch="showSearch"
    :treeCheckStrictly="!showParent"
    optionFilterProp="children"
    :showCheckedStrategy="showParent ? SHOW_ALL() : SHOW_PARENT()"
    :filterTreeNode="filterTreeOption"
    v-else-if="type=='treeSelect'"
    :value="getValue"
    @change="onSelectChange"
    :dropdown-style="{ maxHeight: '300px', overflow: 'auto' }"
    :disabled="disabled || readOnly"
    :treeCheckable="mode == 'multiple'"
    :treeData="dictOptions"
    :replaceFields="replaceFields"
    :placeholder="placeholder"
    :allowClear="allowClear"
    :getPopupContainer="
      triggerNode => {
        return triggerNode.parentNode || document.body;
      }
    "
  >
  </a-tree-select>
  <!--  级联选择框-->
  <a-cascader
    v-else-if="type == 'cascader'"
    :showSearch="showSearch"
    :value="getValue"
    @change="onChange"
    :disabled="disabled || readOnly"
    :options="dictOptions"
    :placeholder="placeholder"
    :allowClear="allowClear"
    :fieldNames="replaceFields"
    :show-search="{ filterCascader }"
    :getPopupContainer="
      triggerNode => {
        return triggerNode.parentNode || document.body;
      }
    "
  >
  </a-cascader>
</template>

<script>

import {ajaxGetDictItems, ajaxGetSqlConfigItems, ajaxGetHttpConfigItems} from '../../utils/api/api';
import pinyin from 'js-pinyin'
import YchConstant from "../../utils/YchConstant";
import {getAction} from "../../utils/manage";
import {SHOW_ALL, SHOW_CHILD, SHOW_PARENT} from "ant-design-vue/lib/vc-tree-select";

export default {
  name: 'DictSelectTag',
  props: {
    type: String,
    dictCode: String,
    sqlCode: String,
    sqlParameterConfig: Array,
    httpConfig: Object,
    options: Array,
    disabled: Boolean,
    readOnly: Boolean,
    placeholder: String,
    value: [String, Number],
    allowClear: Boolean,
    formatExpr: String,
    showSearch: {
      type: Boolean,
      default: false
    },
    showParent: {
      type: Boolean,
      default: false
    },
    mode: String,
    dictMap: {
      type: Object,
      default: () => {
      }
    },
    linkage: String,
    linkageMap: {
      type: Object,
      default: () => {
      }
    },
    // 表单对象
    form: Object,
  },
  data() {
    return {
      initOptions: [],
      dictOptions: [],
      syncNum: 0, // 防止异步
      replaceFields: {
        children: 'children',
        label: 'text',
        value: 'value'
      },
      url: {
        list: YchConstant.PREFIX_EFORM +"/manage/actAppSql/list",
        delete: YchConstant.PREFIX_EFORM +"/manage/actAppSql/delete",
        deleteBatch: YchConstant.PREFIX_EFORM +"/manage/actAppSql/deleteBatch",
        exportXlsUrl: YchConstant.PREFIX_EFORM +"/manage/actAppSql/exportExcel",
        importExcelUrl: YchConstant.PREFIX_EFORM +"/manage/actAppSql/importExcel",
      },
      sqlPid: null,
      sqlId: null,
    }
  },
  computed: {
    getValue() {
      // 下拉框未初始化选项时，不要显示ID
      if (this.type === 'select' && this.dictOptions.length === 0) {
        return undefined
      }
      let value = ''
      if (typeof this.value !== 'number') {
        value = this.value
      } else {
        value = this.value.toString()
      }
      if (this.type == 'checkbox' || (this.type == 'select' && this.mode == 'multiple') || this.type == 'treeSelect' || this.type == 'cascader') {
        if (this.type == 'treeSelect' && this.mode == 'multiple' && !this.showParent){
          let arr = [];
          if (typeof value === 'string') {
            value && value.split(',').forEach(item => {
              arr.push({
                label: this.initOptions.find(itm => itm.value == item) && this.initOptions.find(itm => itm.value == item).title,
                value: item
              })
            })
          }
          return arr
        }
        return value ? value.split(',') : []
      } else {
        return value || undefined
      }
    },
    linkageValue() {
      if (this.linkage && this.linkageMap) {
        const result = {}
        let hasValue = false
        this.linkage.split(",").forEach(key => {
          result[key] = this.linkageMap[key]
          if (result[key] !== undefined && result[key] !== null && result[key] !== "") {
            hasValue = true
          }
        })
        return hasValue ? result : null
      }
      return null
    },
    dictOptionsMap() {
      const result = {}
      this.dictOptions.forEach(item => {
        result[item.value] = item.text || item.label
      })
      return result
    },
  },
  created() {
    //获取字典数据
    this.initDictData();
  },
  watch: {
    dictCode: {
      handler() {
        this.initDictData()
      }
    },
    sqlCode: {
      handler() {
        this.initDictData()
      }
    },
    httpConfig: {
      handler() {
        this.initDictData()
      }
    },
    options: {
      handler() {
        this.initDictData()
      }
    },
    linkageValue: {
      handler(newValue, oldValue) {
        if (JSON.stringify(newValue || {}) === JSON.stringify(oldValue || {})) {
          return
        }
        if (!(this.options && this.options.length > 0) && !this.dictCode && this.sqlCode) {
          this.updateBySqlCode()

          if (oldValue) {
            // 清空选项
            this.$emit('input', null)
            this.$emit('change', null)
          }
        } else if (!(this.options && this.options.length > 0) && !this.dictCode && this.httpConfig && this.httpConfig.httpCode) {
          this.updateByHttpCode()

          if (oldValue) {
            // 清空选项
            this.$emit('input', null)
            this.$emit('change', null)
          }
        }
      }
    }
  },
  methods: {
    SHOW_PARENT() {
      return SHOW_PARENT
    },
    SHOW_ALL() {
      return SHOW_ALL
    },
    SHOW_CHILD () {
      return SHOW_CHILD
    },
    initDictData() {
      if (this.options && this.options.length > 0) {
        this.dictOptions = [...this.options]
        this.formatOptionsByExpr()
      } else if (this.dictCode) {
        if (this.dictMap && this.dictMap.hasOwnProperty(this.dictCode)) {
          this.dictOptions = this.dictMap[this.dictCode];
          this.formatOptionsByExpr()
        } else {
          //根据字典Code, 初始化字典数组
          ajaxGetDictItems(this.dictCode, null).then((res) => {
            if (res.success) {
              this.dictOptions = res.result;
              this.formatOptionsByExpr()
              if (this.dictMap) {
                this.dictMap[this.dictCode] = res.result;
              }
            }
          })
        }
      } else if (this.sqlCode) {
        this.updateBySqlCode()
      } else if (this.httpConfig && this.httpConfig.httpCode) {
        this.updateByHttpCode()
      } else {
        this.dictOptions = [];
      }
    },
    updateBySqlCode() {
      const parameter = {}
      const that = this
      if (this.linkage && this.linkageValue) {
        Object.assign(parameter, this.linkageValue)
      } else if (this.linkage) {
        // 如果要空值查询，需要放开这里
        this.dictOptions = []
        return;
      }
      // 入参
      if (this.sqlParameterConfig && this.sqlParameterConfig.length > 0 && this.form) {
        this.sqlParameterConfig.forEach(item => {
          let value = null;
          if (item.outKey) {
            value = this.form.getFieldValue(item.outKey)
          }
          if (!value && item.defaultValue) {
            value = item.defaultValue
          }
          if (value) {
            parameter[item.parameterKey] = value
          }
        })
      }
      this.syncNum++
      const syncNum = this.syncNum
      ajaxGetSqlConfigItems(this.sqlCode, parameter).then((res) => {
        // 防止异步
        if (syncNum !== this.syncNum) {
          return;
        }
        if (res.success) {
          that.dictOptions = res.result;
          that.initOptions = res.result;
          if (that.type == 'treeSelect' || that.type == 'cascader') {
            getAction(that.url.list,{sqlCode: that.sqlCode}).then((res) => {
              const record = res.result.records[0];
              that.sqlPid = 'sqlPid'
              that.sqlId = 'sqlId'
              if (that.dictOptions.length && that.dictOptions[that.dictOptions.length - 1].hasOwnProperty(that.sqlPid)&& that.dictOptions[that.dictOptions.length - 1].hasOwnProperty(that.sqlId)){
                const list = that.handleTree(that.dictOptions, that.sqlPid, that.sqlId);
                that.dictOptions = list;
                that.formatOptionsByExpr()
              }
            });
          } else {
            that.formatOptionsByExpr()
          }
        }
      })

    },
    // 平铺转结构树
    handleTree(data, Pid, Id) {
      const list = [];
      data.map(item => {  //找到最上层的数据 父级节点为空
        if (!item[Pid] || item[Pid] == '-1' || item[Pid] == 0) {
          list.push(item);
        }
      });
      for (let i = 0; i < list.length; i++) {
        setTree(list[i])
      }
      function setTree(row) {
        row.children = [];
        for (let j = 0; j < data.length; j++) {
          if (data[j][Pid] == row[Id]) { //Id 为子id 当前数据的id
            row.children.push(data[j]);
            setTree(data[j]);
          }
        }
      }
      return list
    },
    updateByHttpCode() {
      const parameter = {}
      if (this.linkage && this.linkageValue) {
        Object.assign(parameter, this.linkageValue)
      } else if (this.linkage) {
        this.dictOptions = []
        return;
      }
      this.syncNum++
      const syncNum = this.syncNum
      parameter.httpConfig = this.httpConfig
      ajaxGetHttpConfigItems(this.httpConfig.httpCode, parameter).then((res) => {
        // 防止异步
        if (syncNum !== this.syncNum) {
          return;
        }
        if (res.success) {
          this.dictOptions = res.result;
          this.formatOptionsByExpr()
        }
      })
    },
    formatOptionsByExpr() {
      if (!this.formatExpr) {
        return;
      }
      this.dictOptions = JSON.parse(JSON.stringify(this.dictOptions))
      this.dictOptions.forEach(item => {
        let value = item.text || item.label
        let key = item.value
        if (value) {
          const text = this.formatExpr.replace(/\$\{key\}/g, !key ? "" : key).replace(/\$\{value\}/g, !value ? "" : value);
          item.text = text
          item.label = text
        }
      })
    },
    onChange(e) {
      let val;
      let text;
      if (this.type == "radio") {
        val = e.target.value;
      } else if (this.type == "checkbox") {
        val = e.join(",");
      } else if (this.type == "select") {
        val = this.mode == 'multiple' ? e.join(",") : e;
        val = val === undefined ? null : val
      } else if (this.type == "treeSelect" || this.type == "cascader") {
        val = this.mode == 'multiple' ? e.join(",") : e;
        val = val === undefined ? null : val
      }
      if (val && val.length > 0) {
        text = val.split(",").map(item => this.dictOptionsMap[item]).join(",")
      }
      this.$emit('input', val);
      this.$emit('change', val, text);
    },
    async onSelectChange (value,label,extr) {
      // function flatten(tree = [], nodes = []) {
      //   for (let item of tree) {
      //     nodes.push(item.node ? item.node.key : item.key)
      //     item.children && flatten(item.children, nodes)
      //   }
      //   return nodes
      // }
      // const flatList = flatten(extr.allCheckedNodes)
      let text;
      let val = this.mode == 'multiple' ? !this.showParent ? value :value.join(",") : value;
      val = val === undefined ? null : val
      if (val && val.length > 0) {
        if (this.mode == 'multiple' && !this.showParent) {
          text = val.map(item => item.label)
          val = val.map(item => item.value).join(",")
        }else{
          text = val.split(",").map(item => this.dictOptionsMap[item]).join(",")
        }
      }else{
        if (this.mode == 'multiple' && !this.showParent) {
          val = ''
        }
      }
      this.$emit('input', val);
      this.$emit('change', val, text);
    },
    filterOption(input, option) {
      let optionValue = option.componentOptions.children[0].text
      let jp = pinyin.getCamelChars(optionValue)
      if (!jp) {
        jp = ''
      }
      if (optionValue.toLowerCase().indexOf(input.toLowerCase()) >= 0
        || jp.toLowerCase().indexOf(input.toLowerCase()) >= 0) {
        return true
      } else {
        return false
      }
    },
    filterTreeOption (input, treeNode) {
      return treeNode.data.props.title.includes(input)
    },
    filterCascader(inputValue, path) {
      return path.some(option => option.label.toLowerCase().indexOf(inputValue.toLowerCase()) > -1);
    },
  }
}
</script>
