<template>
  <div class="w-full">
    <a-transfer
      v-model:target-keys="dataValue"
      class="tree-transfer"
      :data-source="dictList"
      :render="item => item.title"
      :show-select-all="false"
      :show-search="true"
      :disabled="readonly || disabled"
      @change="dataValueChange"
      @search="search"
      :style="{ height: (props.record?.itemHeight || 300) + 'px' }"
    >
      <template #children="{ direction, selectedKeys, onItemSelect, onItemSelectAll }">
        <a-directory-tree
          v-if="direction === 'left'"
          :checked-keys="[...selectedKeys, ...dataValue]"
          :tree-data="treeData"
          checkable
          :show-icon="false"
          @check="
            (_, props) => {
              treeCheck(props, [...selectedKeys, ...dataValue], onItemSelectAll);
            }
          "
          :disabled="readonly || disabled"
          :checkStrictly="props.record?.formItemSelect?.treeCheckStrictly"
        ></a-directory-tree>
      </template>
    </a-transfer>
  </div>
</template>

<script setup name="FormTransfer">
import { debounce } from 'lodash-es';
import { deepClone, searchTree } from '@/utils/common/util';
import { ref, onMounted, watch, computed } from 'vue';
import Request from '@/utils/request/request-util';

const props = defineProps({
  value: {
    type: String,
    default: ''
  },
  //当前行配置
  record: {
    type: Object,
    default: {}
  },
  // 当前行数据
  formData: {
    type: Object,
    default: {}
  },
  //是否禁用
  disabled: {
    type: Boolean,
    default: false
  },
  placeholder: {
    type: String,
    default: '请选择'
  },
  // 是否只读
  readonly: {
    type: Boolean,
    default: false
  },
  // 是否是设计
  isDesgin: {
    type: Boolean,
    default: false
  }
});

const emits = defineEmits(['update:value', 'onChange']);

// 下拉取值 1: id;2: code
const valueType = ref(1);
// 数据来源
const dataFromType = ref(1);

// 选中的值
const dataValue = ref([]);

// 可选中列表
const dictList = ref([]);

// 原始数据
const oldDictList = ref([]);

const transferData = ref([]);

// 是否有关联字段
const linkFieldCode = ref('');

// 左侧数据列表
const treeData = computed(() => {
  return handleTreeData(transferData.value, dataValue.value);
});

onMounted(() => {
  if (props.record?.formItemSelect?.valueType == 2) {
    valueType.value = 2;
  }
  if (props.record?.formItemSelect?.linkFieldCode) {
    linkFieldCode.value = props.record.formItemSelect.linkFieldCode;
  }
  if (props.record?.formItemSelect?.dataFromType) {
    dataFromType.value = props.record.formItemSelect.dataFromType;
  }
  getDictList();
  setValueData();
});

// 获取选择列表
const getDictList = searchText => {
  if (props.isDesgin || dataFromType.value != 1 || !props.record.formItemSelect.backendUrl) return;
  dictList.value = [];
  let params = {
    searchText: searchText
  };
  if (linkFieldCode.value) {
    params[linkFieldCode.value] = props.formData[linkFieldCode.value];
    params.valueType = valueType.value;
  }
  Request.get(props.record.formItemSelect.backendUrl, params).then(res => {
    props.record.dictList = res.data;
  });
};

// 禁用树
const handleTreeData = (treeNodes, targetKeys = []) => {
  return treeNodes.map(({ children, ...props }) => ({
    ...props,
    disabled: targetKeys.includes(props.key),
    children: handleTreeData(children ?? [], targetKeys)
  }));
};

// 左侧树选中
const treeCheck = (e, checkedKeys, onItemSelectAll) => {
  let arr = [];
  arr = e.checkedNodes.map(item => item.key);
  onItemSelectAll(arr, true);
};

// 搜索
const search = (direction, value) => {
  if (direction == 'left') {
    if (dataFromType.value == 1) {
      fetchSearch(value);
    } else {
      // 前端搜索
      const arr = searchTree(transferData.value, oldDictList.value, value);
      transferData.value = [...arr.resultList];
    }
  }
};

// 后端搜索
const fetchSearch = debounce(value => {
  getDictList(value);
}, 500);

// 更改值
const dataValueChange = () => {
  let data = null;
  data = JSON.stringify(dataValue.value);
  emits('update:value', data);
  emits('onChange', props.record);
};

const setValueData = () => {
  if (props.value) {
    dataValue.value = JSON.parse(props.value);
  } else {
    dataValue.value = [];
  }
};

watch(
  () => props.formData[linkFieldCode.value],
  val => {
    getDictList();
  },
  { deep: true }
);

watch(
  () => props.value,
  val => {
    setValueData();
  },
  { deep: true }
);

watch(
  () => props.record.dictList,
  val => {
    if (val) {
      transferData.value = forEachTreeData(val);
      flatten(JSON.parse(JSON.stringify(transferData.value)));
      oldDictList.value = deepClone(transferData.value);
    }
  },
  { deep: true, immediate: true }
);

// 遍历树
const forEachTreeData = treeNodes => {
  return treeNodes?.map(({ children, ...props }) => ({
    ...props,
    key: valueType.value == 1 ? props.id : props.code,
    title: props.name,
    children: forEachTreeData(children ?? [])
  }));
};

const flatten = (list = []) => {
  list.forEach(item => {
    dictList.value.push(item);
    flatten(item.children);
  });
};
</script>

<style scoped lang="less">
.tree-transfer {
  width: 100%;
}
:deep(.ant-transfer-list) {
  background: #fff;
}
:deep(.tree-transfer .ant-transfer-list) {
  width: calc(50% - 20px);
  height: 100%;
  flex: none;
}
:deep(.ant-transfer-list-body-customize-wrapper) {
  overflow-y: auto;
}
</style>
