<template>
  <div class="tree-container">
    <Button v-if="showEdit" type="primary" @click="(formType = 'add') && (show = true)">+&nbsp;&nbsp;新增&nbsp;&nbsp;</Button>
    <Tree
      ref="tree"
      expand-node
      :show-checkbox="showCheckbox"
      :check-strictly="checkStrictly"
      :data="data"
      :render="showEdit? renderEditContent : renderContent"
      @on-check-change="check"
      >
    </Tree>
    <my-modal-form
      v-model="show"
      :title="title"
      :config="formConfig"
      :ruleValidate="ruleValidate"
      :data="formData"
      :type="formType"
      @confirm="cfm"
    >
    </my-modal-form>
  </div>
</template>

<script>
import MyModalForm from './my-modal-form'
export default {
  components: {
    MyModalForm
  },
  props: {
    // 表单校验
    ruleValidate: {
      type: Object,
      default () {
        return {}
      }
    },
    // 表单格式
    formConfig: {
      type: Array,
      default () {
        return []
      }
    },
    // tree数据
    data: {
      type: Array,
      default () {
        return []
      }
    },
    // 是否显示编辑功能按钮
    showEdit: {
      type: Boolean,
      default: true
    },
    // 是否多选
    multiple: {
      type: Boolean,
      default: false
    },
    // 复选框是否关联
    checkStrictly: {
      type: Boolean,
      default: true
    },
    // 显示复选框
    showCheckbox: {
      type: Boolean,
      default: true
    }
  },
  data () {
    return {
      title: '添加',
      formData: {},
      formType: '',
      currentData: {},
      show: false,
      buttonProps: {
        type: 'default',
        size: 'small'
      },
      buttonPropsPrimary: {
        type: 'primary',
        size: 'small'
      }
    }
  },
  methods: {
    /*
    * 树数据操作
    * this.$emit.('handleEvent', type, data, target)
    * type add新增 edit修改 del删除
    * data 当前表单数据
    * target 当前树节点
    * */
    cfm (type, data = {}) {
      this.show = false
      this.$emit('handleEvent', type, data, this.currentData)
      this.currentData = {}
    },
    remove (root, node, data) {
      this.$MyModal.show({ text: '是否删除？' }).$on('confirm', () => {
        this.$emit('handleEvent', 'del', {}, data)
      })
    },
    // 获取选中的所有节点
    getCheckedNodes () {
      return this.$refs.tree.getCheckedNodes()
    },
    // 选中节点 单选返回当前对象 多选返回选中数组
    check (arr, obj) {
      // 多选
      if (this.multiple) {
        console.log(obj.checked ,obj.parentId)
        if (obj.checked && obj.parentId && obj.parentId != '0') {
          /* 子元素勾选 父元素默认勾选 */
          this.data.forEach(item => {
            if (item.value === obj.parentId) {
              this.$set(item, 'checked', true)
            }
          })
        } else if (!obj.checked && obj.parentId) {
          /* 子元素取消 如果父元素下没有勾选的子元素 则取消勾选 */
          this.data.forEach(item => {
            if (item.value === obj.parentId) {
              if (item.children.filter(children => children.checked).length === 0) {
                this.$set(item, 'checked', false)
              }
            }
          })
        } else if (!obj.checked && obj.children) {
          
          /* 父元素取消 取消所有子元素 */
          obj.children.forEach(item => {
            this.$set(item, 'checked', false)
          })
        } else if (obj.checked && obj.children) {
          /* 父元素勾选 选中所有子元素 */
          obj.children.forEach(item => {
            this.$set(item, 'checked', true)
          })
        }
        setTimeout(() => {
          this.$emit('check', this.$refs.tree.getCheckedNodes())
        }, 100)
      } else {
        // 单选
        arr.forEach(item => {
          item.checked = false
        })
        this.$set(obj, 'checked', true)
        this.$emit('check', { ...obj })
      }
    },
    renderContent (h, { root, node, data }) {
      let that = this
      return h('span', {
        style: {
          display: 'inline-block',
          width: '100%'
        }
      }, [
        h('span', {
          style: {
            cursor: 'pointer'
          },
          on: {
            click () {
              that.$set(data, 'checked', !data.checked)
              that.check(that.getCheckedNodes(), data)
            }
          }
        }, data.title)
      ])
    },
    renderEditContent  (h, { root, node, data }) {
      let that = this
      if (data.isHiddenAddBtn) {
        return h('span', {
          style: {
            display: 'inline-block',
            width: '100%',
            backgroundColor: node.node.selected ? '#d5e8fc' : ''
          }
        }, [
          h('span', [
            h('span', {
              attrs: {
                class: 'test'
              },
              style: {
                cursor: 'pointer',
                verticalAlign: 'middle'
              },
              on: {
                click () {
                  if (!node.node.selected) that.$refs.tree.handleSelect(node.nodeKey)
                  that.check(that.getCheckedNodes(), data)
                }
              }
            }, data.title)
          ]),
          h('span', {
            style: {
              display: 'inline-block',
              float: 'right',
              marginRight: '32px'
            }
          },
          [
            h('Button', {
              props: Object.assign({}, this.buttonProps, {
                icon: 'ios-create-outline'
              }),
              style: {
                marginRight: '8px'
              },
              on: {
                click: () => {
                  this.formType = 'edit'
                  this.title = '修改'
                  this.show = true
                  data.code = data.value
                  for (const key in data) {
                    this.formData[key] = data[key]
                  }
                }
              }
            }),
            h('Button', {
              props: Object.assign({}, this.buttonProps, {
                icon: 'ios-remove'
              }),
              on: {
                click: () => { this.remove(root, node, data) }
              }
            })
          ])
        ])
      } else if (data.isHiddenEditBtn) {
        return h('span', {
          style: {
            display: 'inline-block',
            width: '100%'
          }
        }, [
          h('span', [
            h('span', {
              style: {
                cursor: 'pointer'
              },
              on: {
                click () {
                  that.check(that.getCheckedNodes(), data)
                }
              }
            }, data.title)
          ]),
          h('span', {
            style: {
              display: 'inline-block',
              float: 'right',
              marginRight: '24px'
            }
          },
          [
            h('Button', {
              props: Object.assign({}, this.buttonPropsPrimary, {
                icon: 'ios-add'
              }),
              style: {
                marginRight: '8px'
              },
              on: {
                click: () => {
                  this.formType = 'add'
                  this.title = '添加'
                  this.currentData = data
                  this.show = true
                }
              }
            })
          ])
        ])
      } else if (data.isHiddenDelBtn) {
        return h('span', {
          style: {
            display: 'inline-block',
            width: '100%'
          }
        }, [
          h('span', [
            h('span', {
              style: {
                cursor: 'pointer'
              },
              on: {
                click () {
                  that.check(that.getCheckedNodes(), data)
                }
              }
            }, data.title)
          ]),
          h('span', {
            style: {
              display: 'inline-block',
              float: 'right',
              marginRight: '48px'
            }
          },
          [
            h('Button', {
              props: Object.assign({}, this.buttonPropsPrimary, {
                icon: 'ios-add'
              }),
              style: {
                marginRight: '8px'
              },
              on: {
                click: () => {
                  this.formType = 'add'
                  this.title = '添加'
                  this.currentData = data
                  this.show = true
                }
              }
            }),
            h('Button', {
              props: Object.assign({}, this.buttonProps, {
                icon: 'ios-create-outline'
              }),
              style: {
                marginRight: '8px'
              },
              on: {
                click: () => {
                  this.formType = 'edit'
                  this.title = '修改'
                  this.show = true
                  data.code = data.value
                  for (const key in data) {
                    this.formData[key] = data[key]
                  }
                }
              }
            })
          ])
        ])
      } else {
        return h('span', {
          style: {
            display: 'inline-block',
            width: '100%'
          }
        }, [
          h('span', [
            h('span', {
              style: {
                cursor: 'pointer'
              },
              on: {
                click () {
                  that.check(that.getCheckedNodes(), data)
                }
              }
            }, data.title)
          ]),
          h('span', {
            style: {
              display: 'inline-block',
              float: 'right',
              marginRight: '48px'
            }
          },
          [
            h('Button', {
              props: Object.assign({}, this.buttonPropsPrimary, {
                icon: 'ios-add'
              }),
              style: {
                marginRight: '8px'
              },
              on: {
                click: () => {
                  this.formType = 'add'
                  this.title = '添加'
                  this.currentData = data
                  this.show = true
                }
              }
            }),
            h('Button', {
              props: Object.assign({}, this.buttonProps, {
                icon: 'ios-create-outline'
              }),
              style: {
                marginRight: '8px'
              },
              on: {
                click: () => {
                  this.formType = 'edit'
                  this.title = '修改'
                  this.show = true
                  data.code = data.value
                  for (const key in data) {
                    this.formData[key] = data[key]
                  }
                }
              }
            }),
            h('Button', {
              props: Object.assign({}, this.buttonProps, {
                icon: 'ios-remove'
              }),
              on: {
                click: () => { this.remove(root, node, data) }
              }
            })
          ])
        ])
      }
    },
    initData (array) {
      array.forEach(item => {
        item.title = item.name
        if (item.children) {
          this.initData(item.children)
        }
      })
    }
  },
  watch: {
    data: {
      handler (newVal, oldVal) {
        this.initData(this.data)
      },
      deep: true
    }
  },
  mounted () {
  }
}
</script>

<style lang="less" scoped>
.tree-container {
  height: 100%;
  overflow: hidden;
  overflow-y: auto !important;
  min-width: 300px;
}
/deep/.ivu-tree {
  ul {
    font-size: 14px;
  }
}
/deep/.test {
  &:focus {
    background: red;
  }
}
</style>
