<template>
  <div style="display: inline-block;width: 100%">
    <div class="ext-tree-select-display" v-if="!state.init&&state.displays.length>0" @click="handleDisplayClick">
      <template v-if="readonly&&!state.displays">{{ placeholder }}</template>
      <el-tag :key="idx" v-for="(item,idx) in state.displays">{{ item.name || item }}</el-tag>
    </div>
    <el-tree-select
        style="width: 100%"
        v-show="state.init||(state.displays.length===0&&!readonly)"
        ref="extTreeSelectRef"
        v-model="state.modelValue"
        :data="state.treeData"
        :default-check-keys="state.defaultCheckKeys"
        :filter-node-method="filterNodeMethod"
        filterable clearable
        highlight-current
        :placeholder="placeholder"
        :disabled="readonly"
        show-checkbox
        :loading="state.loading"
        :check-on-click-node="state.checkOnClickNode"
        :check-strictly="state.checkStrictly"
        :multiple="multiple"
        :node-key="nodeKey"
        :props="{children:children,label:label}"
        @check="handleTreeCheck"
        @clear="handleSelectClear"
        @visible-change="handleVisibleChange">
      <template #empty>
        <el-empty :image-size="50"/>
      </template>
    </el-tree-select>
  </div>

</template>

<script lang="ts" setup name="ExtTreeSelect">
import {reactive, onMounted, ref, watch} from 'vue';
import {ElMessage} from 'element-plus';
import {$body} from "/@/utils/request";
import u from "/@/utils/u";

const extTreeSelectRef = ref();
const props = defineProps({
  modelValue: {
    type: [Number, Array<Number>]
  },
  multiple: {
    type: Boolean,
    default: false
  },
  mode: {
    type: String,
    default: 'dept'   //dept  user  custom
  },
  children: {
    type: String,
    default: 'children'
  },
  label: {
    type: String,
    default: 'name'
  },
  nodeKey: {
    type: String,
    default: 'id'
  },
  showCheckbox: {
    type: Boolean,
    default: true
  },
  placeholder: {
    type: String,
    default: '请选择'
  },
  readonly: {
    type: Boolean,
    default: false
  },
  displayList: {
    type: [String, Array]
  }
});

const state = reactive({
  treeData: [] as Array<SelectTreeType>,
  checkStrictly: true,  //任何节点都可被选择，否则只有子节点可被选择
  showCheckBox: false, // 复选框
  checkOnClickNode: false, //只有点击当前节点才可被选择
  modelValue: null,
  loading: false,
  init: false,
  displays: [] as Array<any>,
  defaultCheckKeys: []
})

const emit = defineEmits(['update:modelValue', 'on-change']);

watch(() => props.modelValue, (val) => {
  if (state.init) {
    // console.log(val)
    // extTreeSelectRef.value.setCheckNodes(null)
    reactiveModel()
  }
})

// const modelVal = computed(() => props.value);
// const defaultCheckKeys = computed(() => props.value);

const reactiveModel = () => {
  let val = props.modelValue;
  let keys = [];
  if (!props.multiple) {
    keys = val ? [val] : []
  } else {
    keys = val || [];
  }
  console.log("reactiveModel>>>", keys)
  extTreeSelectRef.value.setCheckedKeys(keys);
  if (keys) {
    let nodes = setupCheckNodes(state.treeData, keys)
    extTreeSelectRef.value.setCheckedNodes(nodes);
    console.log(nodes)
  }

}

const setupCheckNodes = (tree: Array<any>, keys: Array<any>) => {
  let result: Array<any> = [];
  tree.forEach((item: any) => {
    if (keys.includes(item.id)) {
      result.push(item)
    }
    if (item.children) {
      let ret = setupCheckNodes(item.children, keys)
      if (ret) {
        result = result.concat(ret);
      }
    }
  })
  return result;
}

const handleDisplayClick = () => {
  state.init = true;
  handleVisibleChange(true)
  extTreeSelectRef.value.focus();
}
const handleVisibleChange = (visible: boolean) => {
  // console.log("visible>>>", visible)
  if (visible) {
    loadData();
  }
}

const handleSelectClear = () => {
  extTreeSelectRef.value.setCheckedNodes([])
  emitData();
}

const handleTreeCheck = () => {
  // console.log(JSON.stringify(val))

  if (!extTreeSelectRef.value) {
    console.error("null select ref")
  }
  emitData();

}

const emitData = () => {
  // console.error(state.modelValue)
  let data = extTreeSelectRef.value.getCheckedNodes();
  // console.error(data)
  if (props.multiple) {
    if (data && data.length > 0) {
      emit("update:modelValue", data.map((k: any) => k[props.nodeKey]));
      emit('on-change', data)
    } else {
      emit("update:modelValue", [])
      emit('on-change', [])

    }
  } else {
    if (data && data.length > 0) {
      emit("update:modelValue", data[0][props.nodeKey])
      emit('on-change', data[0])
    } else {
      emit("update:modelValue", null)
      emit('on-change', null)
    }
  }
}


// const handleCurrentChange = (val,event)=>{
//   console.log(val)
//   console.log(event)
// }

const filterNodeMethod = (value: string, data: any) => {
  // console.log(data, value)
  return data[props.label].includes(value)
}

const recursiveArrayV2 = (treeData: Array<any>) => {
  // let ret: Array<SelectTreeType> = [];
  treeData.forEach(item => {
    if (item.id < 0) {
      item.disabled = true;
    }
    if (!u.isEmptyOrNull(item.children)) {
      recursiveArrayV2(item.children)
    }
  })
}

const loadDeptUserData = () => {
  $body(`/department/treeV2`).then((res: any) => {
    if (!u.isEmptyOrNull(res)) {
      recursiveArrayV2(res)
      // console.log(res)
      state.treeData = res;
      state.loading = false;
      reactiveModel()
    } else {
      ElMessage.info("暂无部门信息");
    }
  })
}


const loadDeptData = () => {
  $body(`/department/tree`).then((res: any) => {
    if (!u.isEmptyOrNull(res)) {
      // let result: Array<SelectTreeType> = recursiveArray([res])
      // console.log(res)
      state.treeData = res;
    } else {
      ElMessage.info("暂无部门信息");
    }
    state.loading = false;
    reactiveModel()
  })
}

const loadData = () => {
  state.init = true;
  //不重复请求接口
  if (state.treeData && state.treeData.length > 0) {
    return;
  }

  state.loading = true;
  if (props.mode === 'user') {
    loadDeptUserData();
    state.checkStrictly = false;
    state.showCheckBox = true;
    // state.checkOnClickNode = true;
  } else if (props.mode === 'dept') {
    loadDeptData();
    state.showCheckBox = true;
    // state.checkStrictly = props.multiple;
  }
}

watch(() => props.displayList, (val) => {
  console.log("displayList",val)
  if (props.displayList) {
    if (props.multiple) {
      state.displays = [...props.displayList]
    } else {
      state.displays = [props.displayList]
    }
  }
  console.log(JSON.stringify(state.displays))
},{deep:true,immediate:true})

onMounted(() => {

});
</script>

<style scoped lang="scss">
.ext-tree-select-display {
  cursor: pointer;
  width: 100%;
  line-height: 32px;
  height: 32px;
  display: inline-flex;
  flex-grow: 1;
  align-items: center;
  //justify-content: center;
  padding: 1px 11px;
  background-color: var(--el-input-bg-color, var(--el-fill-color-blank));
  background-image: none;
  border-radius: var(--el-input-border-radius, var(--el-border-radius-base));
  //transition: var(--el-transition-box-shadow);
  //transform: translate3d(0, 0, 0);
  box-shadow: 0 0 0 1px var(--el-input-border-color, var(--el-border-color)) inset;

  &:hover {
    border: 1px solid var(--el-border-color-hover);
  }
}

</style>