<template>
  <div>
    <selector
      :show-popup="showPopup"
      :value="checkedValue"
      :data-list="listData"
      :cache-data="cacheData"
      :path-data="pathData"
      :multiple="multiple"

      :left-text="leftText"
      :search-placeholder="searchPlaceholder"
      :id-key="idKey"
      :parent-id-key="parentIdKey"
      :value-key="valueKey"
      :label-key="labelKey"
      :children-key="childrenKey"
      :party-type-id="partyTypeId"
      :root-name="$t('components.selector.org')"

      :loading="loading"
      :finished="finished"

      @load-data="loadData"
      @change-path="changePath"
      @toggle-child="toggleChild"
      @loading="changeLoading"
      @init-page-data="initPageData"
      @confirm="onConfirm"
      @cancel="onCancel"
      @click-overlay="clickOverlay"
    />
  </div>
</template>
<script>
import { getScriptValue } from '@/api/platform/form/formDef'// 脚本
import { findTreeData as queryByParentIdOrName, get as getOrgById } from '@/api/platform/org/org'
import { getScriptValue as getTreeDataByScriptValue } from '@/api/platform/form/common'
import ActionUtils from '@/utils/action'
import i18n from '@/utils/i18n' // Internationalization 国际化
import Selector from './selector'
import TreeUtils from '@/utils/tree'

export default {
  components: {
    Selector
  },
  props: {
    value: Array,
    showPopup: Boolean,
    multiple: Boolean,
    leftText: String,
    searchPlaceholder: {
      type: String,
      default: i18n.t('common.input')
    },

    idKey: {
      type: String,
      default: 'id'
    },
    parentIdKey: {
      type: String,
      default: 'parentId'
    },
    valueKey: {
      type: String,
      default: 'id'
    },
    labelKey: {
      type: String,
      default: 'name'
    },
    childrenKey: {
      type: String,
      default: 'children'
    },
    otherFilter: String,
    otherFilterIncludeSub: [String, Boolean],
    otherFilterCondition: {
      type: Object,
      default: () => {
        return {}
      }
    },
    partyTypeId: { // 类型节点ID
      type: [String, Number],
      default: ''
    },
    currentOrgId: { // 用户组ID
      type: [String, Number],
      default: ''
    },
    script: String,
    isUseScope: { // 是否启用范围
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      checkedValue: [],
      pathData: [],
      listData: [],
      cacheData: {}, // 缓存数据
      cacheCheckData: [],
      currentListData: [],
      parentId: '0',

      pagination: {},
      loading: false,
      finished: false,
      refreshing: false,
      resultType: 'init',
      errorType: null,
      resultMessage: null
    }
  },
  watch: {
    value() {
      this.initData(this.value)
    },
    showPopup(val) {
      if (val) {
        this.parentId = '0'
        this.pathData = [{
          id: '', // 处理点击面包屑根id与返回数据根id的冲突
          name: '组织'
        }]
        this.initPageData()
        this.loadData({})
      }
    }
  },
  methods: {
    initData(data) {
      this.checkedValue = []
      if (this.$utils.isEmpty(data)) {
        return
      }
      data.forEach(v => {
        if (this.cacheData[v]) {
          this.checkedValue.push(v)
        } else {
          this.getDataInfo(v)
        }
      })
    },
    /**
     * 获取数据信息
     */
    getDataInfo(id) {
      getOrgById({ orgId: id }).then(response => {
        const data = response.data
        if (this.$utils.isEmpty(data)) {
          return
        }
        this.cacheData[data[this.idKey]] = data
        this.checkedValue.push(data[this.idKey])
        this.$emit('init-data', this.getSelectedData(this.checkedValue))
      }).catch((e) => {
        console.error(e)
      })
    },
    toTree(data) {
      return TreeUtils.transformToTreeFormat(data, {
        idKey: 'id',
        pIdKey: 'parentId',
        childrenKey: 'children'
      })
    },
    // 根据渲染的数据范围类型，筛选目标节点
    filterTreeChildren(treeData, treeScope, nodeId) {
      let data = []
      // 返回设置的范围节点
      if (treeScope === 'root') {
        const currentOrgIds = this.currentOrgId.split(',')
        treeData.forEach(f => {
          if (currentOrgIds.includes(f.id)) {
            f.leaf = true
            data.push(f)
          }
        })
      }
      // 返回点击节点的子节点
      if (treeScope === 'node') {
        const filter = function(datas) {
          datas.find(item => {
            if (item.children && item.children !== []) {
              if (item.id === nodeId) {
                data = item.children
                return
              }
              filter(item.children)
            }
          })
        }
        filter(treeData)
      }
      return data
    },
    loadData(data, isInit) {
      const params = {}
      const type = this.partyTypeId !== '' ? this.partyTypeId : '1'
      const check = this.$utils.isNotEmpty(this.currentOrgId) && (data && data.id === '0') && !this.$store.getters.isSuper
      params.type = type === 'script' ? '2' : type
      params.includeSub = type === '1'
      if (this.isUseScope) {
        // 范围选择器调用
        if (type === '1') {
        // 全部
          params.orgId = this.$utils.isEmpty(data) ? '' : data.id
        } else {
          // 指定范围
          if (type === '3' && (this.$utils.isEmpty(data) || data.id === '0' || data.id === '')) {
            params.partyId = this.currentOrgId
          }
          // 初始化加载
          if (this.$utils.isNotEmpty(data) && data.id !== '0' && data.id !== '') {
            params.orgId = data.id === '0' ? null : check ? this.currentOrgId : data.id
          }
          if (type === '2' && (this.$utils.isNotEmpty(data) && data.id !== '0' && data.id !== '')) {
            params.type = '1'
          }
          // 脚本类型初始化   TODO完善，脚本提供正确后在进行测试。
          if (type === 'script' && this.$utils.isEmpty(data)) {
            this.loading = true
            getScriptValue({
              script: this.script,
              vars: ''
            }).then(response => {
              const data = JSON.parse(response.data)
              this.listData = this.toTree(data)
              this.currentListData = this.listData.concat(this.cacheCheckData)
            })
            this.loading = false
            return
          }
        }
      } else {
        // 普通模式
        params.orgId = data.id === 0 ? null : data.id
      }
      this.loading = true
      // 加载
      queryByParentIdOrName(params).then(response => {
        this.loading = false
        const arr = JSON.parse(JSON.stringify(response.data))
        if (this.isUseScope && type !== '1') {
          let treeData
          if (this.$utils.isEmpty(data)) {
            this.listData = this.toTree(arr)
            this.currentListData = this.listData.concat(this.cacheCheckData)
          } else {
            treeData = data.id !== '' && data.id === '0' ? this.filterTreeChildren(arr, 'root') : type === '3' && data.id !== '' ? this.filterTreeChildren(this.toTree(arr), 'node', data.id) : arr
            this.listData = this.toTree(treeData)
            this.currentListData = this.listData.concat(this.cacheCheckData)
          }
        } else {
          this.listData = this.toTree(arr)
          this.currentListData = this.listData.concat(this.cacheCheckData)
        }
        this.refreshing = false
        this.finished = true
        // 缓存
        if (this.$utils.isNotEmpty(this.listData)) {
          this.listData.forEach((d) => {
            this.cacheData[d[this.valueKey]] = d
          })
        }
      }).catch((e) => {
        ActionUtils.handleErrorData(this, e)
      })
    },
    getSelectedData(data) {
      const result = []
      data.forEach((d) => {
        if (this.cacheData[d]) {
          result.push(this.cacheData[d])
        }
      })
      return result
    },
    onCancel() {
      this.$emit('cancel')
    },
    onConfirm(data, type) {
      const checkData = Array.from(new Set(data))
      const listData = this.currentListData
      const arr = []
      if (this.multiple) {
        for (let i = 0; i < listData.length; i++) {
          for (let l = 0; l < checkData.length; l++) {
            if (listData[i].id === checkData[l]) {
              arr.push(listData[i])
              this.cacheCheckData = arr // 缓存
              break
            }
          }
        }
      } else {
        for (let j = 0; j < listData.length; j++) {
          if (listData[j].id === checkData[0]) {
            arr.push(listData[j])
            this.cacheCheckData = arr // 缓存
            break
          }
        }
      }
      if (type !== 'confirm') return
      this.$emit('confirm', arr)
      this.$emit('callbackData', arr)
      this.cacheCheckData = []
      this.currentListData = []
    },
    clickOverlay() {
      this.$emit('click-overlay')
    },
    toggleChild(data) {
      this.parentId = data.id
      this.pathData.push({ id: data.id, name: data.name })
      this.initPageData()
      this.loadData(data)
    },
    changePath(index, data) {
      this.parentId = this.pathData[index][this.idKey]
      this.pathData.splice(index + 1, this.pathData.length - 1)
      this.initPageData()
      this.loadData(data)
    },
    initPageData() {
      this.pagination = {
        page: 1
      }
      this.finished = false
      this.listData = []
      this.resultType = 'init'
      // this.cacheData = []
    },
    changeLoading(data) {
      this.loading = data
    },
    loadDataByScript() {
      getTreeDataByScriptValue({ 'script': this.otherFilterCondition.scriptContent }).then(response => {
        this.listData = response.data.dataResult
        this.loading = false
        this.refreshing = false
        this.finished = true
        // 缓存
        if (this.$utils.isNotEmpty(this.listData)) {
          this.listData.forEach((d) => {
            // d[this.labelKey] = d[this.labelKey]
            this.cacheData[d[this.valueKey]] = d
          })
        }
      }).catch((e) => {
        ActionUtils.handleErrorData(this, e)
      })
    }
  }
}
</script>
