<template>
  <el-cascader
    ref="org"
    :options="options"
    :props="props"
    :change-on-select="changeOnSelect"
    :show-all-levels="showAllLevels"
    :show-root="showRoot"
    :isLazy="isLazy"
    :excLevel="excLevel"
    :placeholder="placeholder"
    :annual="annual"
    :disabled="disabled"
    v-model="selectedOptions"
    @change="handleChange"
  />
</template>

<script>
import { CheckboxButton } from "element-ui";
import api from "../api/comm/apiComm";
export default {
  name: "OrgCascader",
  componentName: "OrgCascader",
  props: {
    root: {
      type: String
      //default: () => '.'
    },
    model: {
      type: String,
      default: () => "organization"
    },
    excLevel: {
      type: String,
      default: () => "11S,11W"
    },
    showAllLevels: {
      type: Boolean,
      default: () => false
    },
    changeOnSelect: {
      type: Boolean,
      default: () => true
    },
    showRoot: {
      type: Boolean,
      default: () => true
    },
    disabled: {
      type: Boolean,
      default: () => false
    },
    isLazy: {
      type: Boolean,
      default: () => false
    },
    onlyEnable: {
      type: Boolean,
      default: () => true
    },
    code: { type: String },
    name: { type: String },
    orgId: { type: String },
    annual: {
      type: String,
      default: () => "0"
    },
    placeholder: { type: String, default: () => "请选择" },
    onchange: Function
  },
  data() {
    return {
      emitVal: "",
      options: [],
      selectedOptions: [],
      props: {
        lazy: this.isLazy,
        lazyLoad: (node, resolve) => {
          // console.log(this);
          if (node.level == 0) {
            return;
          }

          if (node.data.type === "district") {
            Promise.all([
              api.getDistrictChildrenTree(node.data.id, false, this.onlyEnable)
            ])
              .then(([response]) => {
                let children = [];
                for (let x in response) {
                  let obj = {
                    children: [],
                    id: "",
                    code: "",
                    lead: "",
                    leaf: false,
                    level: "",
                    name: "",
                    type: ""
                  };
                  obj.children = response[x].children;
                  obj.id = response[x].id;
                  obj.code = response[x].code;
                  obj.lead = response[x].lead;
                  obj.level = response[x].level;
                  obj.name = response[x].name;
                  obj.leaf = response[x].leaf;
                  obj.type = response[x].type;
                  children.push(obj);
                }
                resolve(children);
              })
              .catch(error => {});
          } else if (node.data.type === "organization") {
            Promise.all([
              api.getOrgTreeByLead(
                node.data.id,
                this.annual,
                false,
                this.onlyEnable,
                this.isLazy,
                this.excLevel
              )
            ])
              .then(([response]) => {
                let children = [];
                for (let x in response) {
                  let obj = {
                    children: [],
                    id: "",
                    code: "",
                    lead: "",
                    leaf: false,
                    level: "",
                    name: "",
                    type: ""
                  };
                  obj.children = response[x].children;
                  obj.id = response[x].id;
                  obj.code = response[x].code;
                  obj.lead = response[x].lead;
                  obj.level = response[x].level;
                  obj.name = response[x].name;
                  obj.leaf = response[x].leaf;
                  obj.type = response[x].type;
                  children.push(obj);
                }
                resolve(children);
              })
              .catch(error => {});
          }
        },
        value: "id",
        label: "name"
      }
    };
  },
  created() {
    this.loadCasData();
  },
  computed: {
    org() {
      return this.$refs.org;
    }
  },
  watch: {
    orgId(curVal, oldVal) {
      if (curVal != this.emitVal) {
        if (!this.isNullOrEmpty(curVal) && curVal != oldVal) {
          //console.log("OrganizationForm:target orgId changed:" + curVal);
          this.loadCasData();
        } else {
          this.createValue();
        }
      }
    },
    root(curVal, oldVal) {
      if (curVal && curVal != oldVal) {
        this.loadCasData();
      }
    },
    onchange(curFun, oldFun) {
      // console.log("curFun", curFun);
      // console.log("oldFun", oldFun);
      this.onchange = curFun;
    }
  },
  methods: {
    handleChange(value) {
      if (value.length === 0) {
        this.$emit("update:code", this.options[0].id);
        this.$emit("update:name", this.options[0].name);
        this.$emit("onchange", "", "", [], value); // 将当前对象 evt 传递到父组件
      } else {
        this.$emit("update:code", value[value.length - 1]);
        setTimeout(() => {
          this.setLabel(value);
        }, 1);
      }
    },
    setLabel(value) {
      this.emitVal = value[value.length - 1];
      let labels = this.$refs["org"].presentText;
      if (this.showAllLevels) {
        labels = labels.split(" / ");
        this.$emit("update:name", labels[labels.length - 1]);
        this.$emit(
          "onchange",
          labels[labels.length - 1],
          //labels,
          value[value.length - 1],
          labels,
          value
        );
      } else {
        this.$emit("update:name", labels);
        this.$emit(
          "onchange",
          //labels[labels.length - 1],
          labels,
          value[value.length - 1],
          labels,
          value
        );
      }
    },
    loadCasData() {
      const { root, orgId, model } = this;
      Promise.all([this.loadOpt()])
        .then(([res]) => {
          let result = [];
          if (res instanceof Array) {
            result = res;
          } else {
            result.push(res);
          }

          this.resetCasStatus();
          this.options = result;
          //阻止option和activePath同步更新导致不能正确刷新pannel
          if (!this.isNullOrEmpty(root)) {
            this.$nextTick(() => {
              this.createValue(result);
            });
          }
        })
        .catch(error => {
          console.log(error);
        });
    },
    createValue(options) {
      const { root, orgId } = this;
      this.resetCasStatus();
      if (!this.showRoot) {
        return;
      }

      if (orgId === "" || orgId === undefined || orgId === null) {
        this.selectedOptions = [root];
      } else {
        if (this.model == "district") {
          this.createDisValue(options);
        } else {
          this.createOrgValue(options);
        }
      }
    },
    createDisValue(options) {
      let path = [];
      while (options && options.length) {
        options.some((option, index) => {
          if (this.orgId.indexOf(option.id) !== -1) {
            path.push(option.id);
            options = option.children;
            return true;
          }
          if (index === options.length - 1) {
            options = null;
            return true;
          }
          return false;
        });
      }
      this.selectedOptions = path;
    },
    createOrgValue(options) {
      let path = [];
      while (options && options.length) {
        options.some((option, index) => {
          if (this.orgId.indexOf(option.id) !== -1) {
            path.push(option.id);
            options = option.children;
            return true;
          }
          if (index === options.length - 1) {
            options = null;
            return true;
          }
          return false;
        });
      }
      this.selectedOptions = path;
    },
    loadOpt() {
      return this.model == "district" ? this.loadDisOpt() : this.loadOrgOpt();
    },
    loadDisOpt() {
      const { root, districtId, isLazy } = this;
      if (isLazy) {
        if (
          this.isNullOrEmpty(districtId) ||
          districtId.length < root.length ||
          districtId == root
        ) {
          return api.getDistrictChildrenTree(this.root, true, this.onlyEnable);
        } else {
          return api.getDistrictSimpleTreeByLead(root, districtId);
        }
      } else {
        return api.getDistrictTreeByLead(
          this.root,
          this.annual,
          this.onlyEnable
        );
      }
    },
    loadOrgOpt() {
      const { root, orgId, isLazy } = this;
      return api.getOrgTreeByLead(
        this.root,
        this.annual,
        true,
        this.onlyEnable,
        isLazy,
        this.excLevel
      );
    },
    resetCasStatus() {
      //重置级联选择器展开状态
      //如果不重置，级联选择器会保持之前展开状态，更新orgId不会显示正确的路径
      this.$refs.org.panel.activePath = [];
    },
    isNullOrEmpty(value) {
      return value == null || value == "";
    }
  }
};
</script>
