<template>
	<div class="xd-cascade-panel">
		<div class="xd-cascade-panel__operate">
			<div :class="{disabled: disabled}">
				<el-cascader-panel
					@change="update"
					ref="xdCascadePanel"
					v-model="cascade"
					:style="{height: height}"
					:options="uiList"
					:props="props"
					filterable
					clearable
					collapse-tags
          disabled
				>
				</el-cascader-panel>
			</div>
		</div>
		<div class="xd-cascade-panel__tips" v-if="setting.tips" v-html="setting.tips"></div>
	</div>
</template>

<script>
  import emitter from 'element-ui/src/mixins/emitter';

  export default {
    name: "XdCascadePanel",
    mixins: [emitter],
		props:{
      defaultValue: {
        type: Array,
        default() {
          return []
        },
      },

      maps: {
        type: Object | null,
        default() {
          return null
        },
      },

			list: {
        type: Array | null,
        default() {
          return null
        },
			},

      setting: {
        type: Object,
        default() {
          return {
            height: '260px', //面板高度
            tips: '', //是否显示提示文案
						isBackLeaf: true, //是否只返回叶子节点
          }
        },
      },

      disabled: {
        type: Boolean,
        default: false,
      },

      size: {
        type: String,
        default: 'medium', //medium / small / mini
      },

      placeholder: {
        type: Object,
        default() {
          return {

          }
        },
      },

      required: {
        type: Boolean,
        default: false,
      },

      //是否启用自定义校验器
      useCustomRules: {
        type: Boolean,
        default: false,
      },

      //数字字符串 转 数字
      isNumber: {
        type: Boolean,
        default: true,
      },

      //自定义方法
      handleCustom: {
        type: Function || null,
        default: null
      },

		},
    watch: {
      loading() {
        this.handleMapToList();
      }
    },
		data(){
      return {
				//默认map关系显示
        defaultMap: {
          value: 'value',
          label: 'label'
        },
        uiList: [],
        height: '260px',
        props: {
          multiple: true,
          checkStrictly: false,
          emitPath: false
        },
        cascade: [],
        isBackLeaf: true,
        initStatus:false,
        isGeRoot: false, //返回值节点的当子集合选择返回父节点选

        loading: false,
			}
		},

		created(){
      if(this.list === null) this.uiList = this.testData;
      else this.uiList = this.list
      this.height = this.$xdHelper.isPC() ?
        (this.setting.height ? this.setting.height : '260px')
        : '220px';
      if (this.setting.isBackLeaf !== undefined) this.isBackLeaf = this.setting.isBackLeaf;
      if (this.setting.isGeRoot !== undefined) this.isGeRoot = this.setting.isGeRoot;
      //props
      if (this.setting.multiple !== undefined) {
        this.$set(this.props, 'multiple', this.setting.multiple);
      }
      if (this.setting.checkStrictly !== undefined) {
        this.$set(this.props, 'checkStrictly', this.setting.checkStrictly);
      }

      //设置默认值为空时候处理
      this.$nextTick(() => {
        this.loading = true;
      })

		},

		methods: {
      //==Root==================
      getRootNodes(){
        let data = {};
        let nodes = this.$refs['xdCascadePanel'].getCheckedNodes(this.isBackLeaf);
        const nodeFn = (node) => {
          if (node.parent === null) {
            data[node.value] = node;
          } else nodeFn(node.parent);
        };
        nodes.map(item => {
          nodeFn(item)
        });
        return Object.keys(data).map(key=>{
          return data[key]
				});
			},

      getRootNodesValue(){
        let nodes = this.getRootNodes();
        let list = [];
        const handle = (root) => {
          let len = root.length;
          for (let i = 0; i < len; i++) {
            //有子节点并且半选时候
            if (root[i].children.length > 0
              && root[i].indeterminate === true
            ) {
              handle(root[i].children);
            } else {
              if (root[i].checked) list.push({
                ...this.getNodeData([root[i]])[0],
                //...root[i].data
              });
            }
          }
        };
        handle(nodes);
        return list;
			},

      getRootValueForLeafValue(select) {
        let selectValue = [];
        let data = this.$xdHelper.cloneDeep(this.uiList);
        const handle = (root, parentData) => {
          let len = root.length;
          for (let i = 0; i < len; i++) {
            //判断当前节点是否已经选中
            root[i].checked = select.filter(val => {
              return val === root[i].value;
            }).length > 0;

            //父级已经选中
            if(parentData && parentData.checked) root[i].checked = true;

            //检查最后一层是否为选中
            if((!root[i].children || root[i].children.length === 0)
							&& root[i].checked
						) {
              selectValue.push(root[i].value);
						}

            if (root[i].children && root[i].children.length > 0) {
              handle(root[i].children, root[i]);
            }
          }
        };
        handle(data, null);
        this.cascade = selectValue;
      },
      //==Root==================

      /**
       * @description 获取node级联 数据项名称与数据项值
       * @param nodes {Object} 数据项节点
       */
      getNodeData(nodes) {
        let nodeDataName = [];
        let nodeDataValue = [];
        const nodeFn = (node) => {
          nodeDataName.unshift(node.label);
          nodeDataValue.unshift(node.value);
          if (node.parent === null) return;
          else nodeFn(node.parent);
        };
        return nodes.map((item) => {
          nodeDataName = [];
          nodeDataValue = [];
          nodeFn(item);
          return {
            labelAll: nodeDataName,
            valueAll: nodeDataValue,
						value: nodeDataValue[nodeDataValue.length-1],
            label: nodeDataName[nodeDataName.length - 1]
          }
        })
      },

      /**
       * @description 单选模式设置默认值
       * @param select {*} 选中的值
       */
      selectOne(select) {
        let selectArr = [];
        const handle = (root, rootLabel = []) => {
          let len = root.length;
          for (let i = 0; i < len; i++) {
            if (root[i].children && root[i].children.length > 0) {
              rootLabel.push(root[i].value)
              handle(root[i].children, rootLabel);
            } else {
              if (select === root[i].value) {
                rootLabel.push(root[i].value);
                selectArr = this.$xdHelper.cloneDeep(rootLabel);
              }
            }
          }
        };
        handle(this.list);
        return selectArr;

      },

      /**
       * @description 返回映射关系对象数据（需要自己实现）
			 * 把内部数据转化为返回数据格式
       */
      handleListToMap() {
        let nodes = this.getNodeData(this.$refs['xdCascadePanel'].getCheckedNodes(this.isBackLeaf));

        //多选并且需要获取子集已全选返回父级数据
        if(this.props.multiple && this.isGeRoot) {
          return this.getRootNodesValue();
				}

        return nodes.map(item => {
          let temp = {};
          Object.keys(item).map(key => {
            let str = this.getMap(key, false);
            if(str) {
              temp[str] = item[key];
						}
            else{
              temp[key] = item[key];
						}
          });
          return temp;
        });
      },

      /**
       * @description 初始化映射关系到数据列表(需要自己实现)
			 * 把默认数据转化为内部数据
       */
      handleMapToList() {
        if (this.defaultValue !== null && this.defaultValue && this.defaultValue.length > 0) {
          let cascade = [];
          if (this.$xdHelper.checkVarType(this.defaultValue[0]) === 'object') {
            this.defaultValue.map(item => {
              Object.keys(item).map(key => {
                let keyStr = this.getMap(key, true);
                if (keyStr && keyStr === 'value') {
                  cascade.push(item[key]);
                }
              })
            });
          }
          else {
            cascade = this.defaultValue
          }

          //多选并且需要获取子集已全选返回父级数据
          //复选模式设置默认值
          if (this.props.multiple) {
            //设置父节点为选择模式
            if (this.isGeRoot) {
              this.getRootValueForLeafValue(cascade);
              this.$nextTick(() => {
                setTimeout(() => {
                  this.update();
                }, 300)
              })
            }
            //子节点选择模式
            else {
              this.cascade = cascade;
              this.$nextTick(() => {
                setTimeout(() => {
                  this.update();
                }, 300)
              })
            }
          }
          //单选模式设置默认值
          else {
            this.cascade = this.selectOne(cascade[0]);
            this.$nextTick(() => {
              setTimeout(() => {
                this.update();
              }, 300)
            })
          }

        }
        this.$nextTick(() => {
          //绑定数据
          this.update();
        })
      },

      //插件系统方法///////////////////////////////////////
      /**
       * @description 获取Maps中键与值
       * @param type {boolean} 返回值类型  true=>获取键  false=>值
       * @param keyword {string} 查找关键字
       * @return {null|string} null=>未找到  string=>找到
       */
      getMap(keyword, type) {
        let maps = null;
        let value = null;
        if (this.maps !== null && !this.$xdHelper.isEmpty(this.maps)) {
          maps = this.$xdHelper.cloneDeep(this.maps);
        }

        //先默认maps关系中找
        Object.keys(this.defaultMap).map(ky => {
          //获取键
          if (type) {
            if (this.defaultMap[ky] === keyword) {
              value = ky;
            }
          } else {
            if (this.defaultMap[keyword]) value = this.defaultMap[keyword];
          }
        });

        //无外部map关系并且在默认关系表中无键
        if (value === null && maps === null) {
          //console.log('1')
          return null;
        }

        //无外部map关系并且在默认关系表中键
        if (value !== null && maps === null) {
          //console.log('2', value)
          return value;
        }

        //有外部map关系进行查找
        Object.keys(maps).map(ky => {
          //获取键
          if (type) {
            if (maps[ky] === keyword) {
              value = ky;
            }
          } else {
            if (this.maps[keyword]) value = this.maps[keyword];
          }
        });
        //console.log('3')
        return value;

      },


      /**
			 * @description 需要校验检查参数是正确处理方法
       */
			checkParams(){
        if (!this.required) return this.handleListToMap();

        //校验成功
        return this.handleListToMap();
			},

			/**
			 * @description 数据改变事件
			 */
			change(){
			  this.$emit('onChange', this.checkParams())
			},


      /**
			 * @description 双向绑定数据处理
       */
			update(){
        console.log('update',this.checkParams())
        this.$emit('input', this.checkParams())
        if (this.$parent.$options['componentName'] === 'ElFormItem') {
          this.dispatch('ElFormItem', 'el.form.change', [this.checkParams()]);
          this.dispatch('ElFormItem', 'el.form.blur', [this.checkParams()])
        }
			},


		}
  }
</script>

<style scoped lang="scss">
	.xd-cascade-panel {

		::v-deep .el-cascader-menu,
		::v-deep .el-cascader-menu__wrap {
			height: 100%;
		}

		&__show {
			margin-bottom: 15px;
		}

		&__tips {
			line-height: 22px;
			font-size: 12px;
			color: #999;
		}

		&__operate {
			width: 100%;
			overflow-x: auto;
			margin-bottom: 10px;

			& > div:first-child {
				display: flex;
				justify-items: flex-start;
			}
      & > div.disabled {
        position: relative;
        &::after{
          position: absolute;
          border-radius: 6px;
          left: 0;
          right: 15px;
          bottom: 0;
          top:0;
          content: ' ';
          cursor: not-allowed;
          background: rgba(0,0,0,.03);
        }
      }
		}

		&__btn {
			margin: 20px 0;
		}
	}

	@media screen and (max-width: 768px) {
		.xd-cascade-panel {
			&__show {
				margin-bottom: 5px;
			}

			&__btn {
				margin: 5px 0;
			}

			&__operate {
				padding-bottom: 10px;
				margin-bottom: 0;

			}
		}
	}
</style>
