<template>
  <TreeSelect
    :class="[style && Object.keys(style).length > 0 ? 'customStyle' : '']"
    v-model:value="checked"
    :style="{ width: width, textAlign: 'left' }"
    :dropdown-style="{ maxHeight: '400px', overflow: 'auto' }"
    placeholder="请选择"
    allow-clear
    :disabled="disabled"
    tree-default-expand-all
    :tree-data="treeData"
    :dropdownMatchSelectWidth="false"
    :field-names="{ children: 'children', value: 'id' }"
    @change="handleChange"
    @select="handleSelect"
    showSearch
    treeNodeFilterProp="name"
    :treeNodeLabelProp="nodeLabel"
  />
</template>
<script lang="ts" setup>
  import { TreeSelect, Tag } from 'ant-design-vue';
  import { onMounted, ref, watch, h, computed } from 'vue';
  import { getDepartmentTree } from '/@/api/system/department';

  const treeData = ref<Recordable[]>([]);

  const props = defineProps({
    value: String,
    isShowAllName: {
      type: Boolean,
      default: false,
    },
    style: Object,
    width: String,
    disabled: Boolean,
  });

  const checked = ref(undefined);
  const nodeLabel = computed(() => {
    return props.isShowAllName ? 'fullName' : 'name';
  });
  const emit = defineEmits(['options-change', 'update:value']);

  // Embedded in the form, just use the hook binding to perform form verification
  onMounted(() => {
    fetch();
  });

  async function fetch() {
    treeData.value = ((await getDepartmentTree()) as unknown as Recordable[]) || [];
    watch(
      () => props.value,
      async (val: any) => {
        checked.value = val || undefined;
        if (val) {
          handleSelect(val);
        }
      },
      {
        immediate: true,
      },
    );
    setTitle(treeData.value);
    emit('options-change', treeData.value);
  }

  //多选
  // function handleChange(...args) {
  //   emit('change', ...args);
  // }

  //单选
  function handleChange(value) {
    emit('update:value', value || '');
  }

  function handleSelect(value) {
    const info = getAllParentNodes(treeData.value, value);
    if (info) {
      const names = info.join('/');
      changeFullName(treeData.value, value, names);
    }
  }
  function changeFullName(data, id, names) {
    data.map((item) => {
      if (item.id === id) {
        item.fullName = names;
      } else if (item.children && item.children.length) {
        changeFullName(item.children, id, names);
      }
    });
  }

  function setTitle(data) {
    data.map((item) => {
      let render: any = null;
      if (item.departmentType === 0) {
        render = h(Tag, { color: 'warning' }, () => '部门');
      } else if (item.departmentType === 1) {
        render = h(Tag, { color: 'processing' }, () => '公司');
      }
      item.title = h('div', {}, [render, h('span', {}, item.name)]);
      if (item.children && item.children.length) {
        setTitle(item.children);
      }
    });
  }
  function getAllParentNodes(list, id) {
    for (let i in list) {
      if (list[i].id === id) {
        return [list[i].name];
      }
      if (list[i].children?.length) {
        let node = getAllParentNodes(list[i].children, id);
        if (node) {
          node.unshift(list[i].name);
          return node;
        }
      }
    }
  }
  const color = computed(() => {
    return props.style?.color;
  });
  const backgroundcolor = computed(() => {
    return props.style
      ? props.style['background-color'] || (props.disabled ? '#f5f5f5' : '#fff')
      : '#fff';
  });
  const border = computed(() => {
    return props.style?.border || '1px solid #d9d9d9';
  });
  const fontsize = computed(() => {
    return props.style ? props.style['font-size'] : '14px';
  });
  const fontstyle = computed(() => {
    return props.style ? props.style['font-style'] : 'normal';
  });
  const customwidth = computed(() => {
    return props.style?.width;
  });
  const height = computed(() => {
    return props.style?.height || '32px';
  });
  const textalign = computed(() => {
    return props.style ? props.style['text-align'] : 'left';
  });
</script>
<style scoped lang="less">
  .customStyle {
    width: v-bind(customwidth) !important;

    &.ant-select-disabled {
      :deep(.ant-select-selector) {
        background-color: v-bind(backgroundcolor);
      }
    }

    :deep(.ant-select-selector) {
      border: v-bind(border) !important;
      height: v-bind(height);
      line-height: v-bind(height);
      background-color: v-bind(backgroundcolor);
      font-size: v-bind(fontsize);
      font-style: v-bind(fontstyle);
      text-align: v-bind(textalign);

      .ant-select-selection-placeholder {
        line-height: v-bind(height);
      }

      .ant-select-selection-item {
        line-height: v-bind(height);
        color: v-bind(color);
      }
    }
  }
</style>
