import { Cascader, Icon } from 'ant-design-vue'
import { UPCLOUD_RDC_TMS_MAINDATA_SERVICE } from '@/config/serviceSettings.js'
const csMaindata = UPCLOUD_RDC_TMS_MAINDATA_SERVICE

let { model } = Cascader
export default {
  name: 'pCascaderZone',
  props: {
    ...Cascader.props,
    url: { type: String, default: csMaindata + '/zone/get-by-pid' },
    placeholder: { type: String, default: '省/市/区/乡(镇)街道' },
    method: { type: String, default: 'post' },
    paramKey: { type: String, default: 'fatherid' },
    baseId: { type: String, default: '01' },
    value: { type: [String, Array] },
    level: { type: Number, default: 4 },
    mode: { type: String, default: 'cascader' },
    fieldNames: {
      type: Object,
      default: () => ({ label: 'zname', value: 'zoneid', children: 'children' })
    },
    allowClear: { type: Boolean, default: false },

  },
  model,
  data() {
    return {
      vOptions: this.options,
      vParams: { [this.paramKey]: this.value },
      ext: true,
      loading: false,
      visible: false,
      // 请求优先级概念,避免请求覆盖
      priority: -1
    }
  },
  watch: {
    value(v) {
      v&& this.getTreeList([this.baseId, ...v])
    },
    options(value) {
      this.vOptions = value
    }
  },
  mounted() {
    if (this.value && this.options.length === 0) {
      this.getTreeList([this.baseId, ...this.value])
    } else if (this.options.length === 0) {
      this.getTreeList([this.baseId])
    }
  },
  methods: {
    resultTreeNodes(data, key) {
      const level = this.level + 1
      data = data.filter(item => item.zlevel <= level)
      let map = {}
      data.forEach(item => {
        delete item.children
        map[item[key]] = item
      })
      let value = []
      data.forEach(item => {
        const p = map[item[this.paramKey]]
        if (p) {
          if (!p.children) {
            p.children = []
          }
          p.children.push(item)
        } else {
          if (item[this.paramKey] == this.baseId) {
            value.push(item)
          }
        }
      }, this)
      return value
    },
    getTreeList(params) {
      const priority = params.length
      return this.getZone({ [this.paramKey]: params.join(',') }).then(data => {
        if (data.length > 0 && priority >= this.priority) {
          this.vOptions = this.resultTreeNodes(data, this.fieldNames.value)
          this.priority = priority
        }
      })
    },
    getZone(params) {
      let self = this
      const { url, method } = this
      let config = { url, method }
      config[method?.toLowerCase() === 'get' ? 'params' : 'data'] = params
      this.loading = true
      let level = this.level + 1
      return this.axios(config)
        .then(res => {
          if (res.success) {
            return res.data.map(item => ({ ...item, isLeaf: item.zlevel >= level }))
          } else {
            self.$message.error(res.message)
          }
        })
        .catch(err => {
          self.$message.error(JSON.stringify(err))
        })
        .finally(() => {
          this.loading = false
        })
    },
    handleLoadData(selectedOptions) {
      let targetOption = null
      if (selectedOptions.length > 0) {
        targetOption = selectedOptions[selectedOptions.length - 1]
        targetOption.loading = true
        this.vParams = { [this.paramKey]: targetOption[this.fieldNames.value] }
      }

      return this.getZone(this.vParams).then(data => {
        if (targetOption && selectedOptions.length > 0) {
          targetOption.loading = false
          targetOption.children = data
          this.vOptions = [...this.vOptions]
        } else {
          this.vOptions = data
        }
        this.$emit('loadData', this.vOptions)
      })
    },
    onChange(value, selectedOptions) {
      this.$emit('change', value, selectedOptions)
    },
    onPopupVisibleChange(open) {
      if (this.disabled) return
      this.visible = open
      this.$emit('popupVisibleChange', this.visible)
    },
    filter(inputValue, path) {
      return path.some(option => option.keyvalue.indexOf(inputValue) > -1)
    }
  },
  render(h) {
    let { fieldNames, placeholder, value, disabled } = this.$props

    if (!Array.isArray(value)) value = []
    let config = {
      props: {
        ...this.$props,

        disabled,
        options: this.vOptions,
        placeholder,
        fieldNames,
        changeOnSelect: true,
        value,
        popupVisible: this.visible,
        loadData: this.handleLoadData,
        allowClear:true,
        //showSearch: { filter: this.filter }
      },
      scopedSlots: {
        suffixIcon: () => {
          return this._c(Icon, {
            props: {
              type: this.loading ? 'loading' : this.visible ? 'up' : 'down'
            }
          })
        }
      },
      on: {
        change: this.onChange,
        popupVisibleChange: this.onPopupVisibleChange
      }
    }

    return h(Cascader, config)
  }
}
