<template>
  <div class="bshztreedialog">
    <el-dialog title="风险单元选择" width="70%" v-model="props.showdialog" @close="closeDialog"  :close-on-click-modal="false"
      :show-close="true">
      <div class="departmentTree-box" :style="{ width: width, height: '100%', }">
        <div class="depar_foot">
          <!-- 改为多选树 -->
          <el-tree ref="treeRef" class="filter-tree" :props="endProps" node-key="id" :default-expanded-keys="expandKeys"
            @node-click="nodeClick" :data="treeData" highlight-current :current-node-key="nodeobj.id"
            :check-on-click-node="false" show-checkbox :check-strictly="true" @check="handleCheck">
            <template #default="{ node }">
              <span class="prefix" :class="{ 'is-leaf': node.isLeaf }">
                <img :src="getImgUrl('img/zzjgli.png')" alt="">
              </span>
              <span>{{ node.label }}</span>
            </template>
          </el-tree>
        </div>
      </div>
      <template #footer>
        <span class="dialog-footer">
          <el-button type="primary" @click="handleSave">
            <el-icon>
              <DocumentChecked />
            </el-icon>
            <span>确定</span>
          </el-button>
          <el-button @click="handleClose" type="primary">
            <el-icon>
              <DocumentDelete />
            </el-icon>
            <span>关闭</span>
          </el-button>
        </span>
      </template>
    </el-dialog>
  </div>
</template>
<script setup>
import { getImgUrl } from "@/utils/tools.js"
import { ref, defineProps, defineEmits, watch, onMounted, reactive, nextTick } from "vue";
import { getApi } from "@/api/tobAcco_api.js";
import { ElMessage } from "element-plus";
const props = defineProps({
  multiple: {
    default: true,  // 改为默认多选
    type: Boolean
  },
  filterable: {
    default: true,
    type: Boolean
  },
  modelValue: {
    type: [String, Array]  // 支持字符串或数组
  },
  showdialog: {
    type: Boolean,
    default: false
  },
  selectedData: {
    type: Array,
    default: []
  }
});
const endProps = {
  children: "children",
  value: "id",
  label: "name",
  isLeaf: "leaf",
  disabled: (data) => {
    // 如果有子节点，就禁用选择（只能选择叶子节点）
    return data.children && data.children.length > 0;
  }
};
const treeRef = ref(null);
const nodeobj = reactive({
  id: undefined
})
/** 默认展开的节点 */
const expandKeys = ref([]);
const treeData = ref([]);
const width = ref();
// 存储多个选中节点
const selectedNodes = ref([]);
const selectedLev1Nodes = ref([]);
// 添加一个标志来跟踪是否已经设置了选中状态
const hasSetSelectedNodes = ref(false);
const emits = defineEmits(["update:modelValue", "change", "dialogshow", "save"]);
onMounted(() => { getTreeData() });
// 防抖处理
watch(() => treeData.value.length, () => {
  if (treeData.value?.length > 0) {
    const root = treeData.value[0];
    expandLastLevel(root, 0);
  }
})

function expandLastLevel (node, level) {
  if (level === 0) {
    node.expanded = true;
  } else if (node.children && node.children.length > 0) {
    node.children.forEach((child) => {
      expandLastLevel(child, level - 1);
    });
  }
}

/**获取默认展开的节点，展开第一个的第一个的第一个的第一个 */
function getExpandFirstArr (arr, expandArr) {
  arr = Array.isArray(arr) ? arr : []
  let first = arr[0]
  if (first) {
    if (first.children?.length > 0) {
      expandArr.push(first.id)
      return getExpandFirstArr(first.children, expandArr)
    } else {
      return expandArr
    }
  } else {
    return expandArr
  }
}

function getFirstAndFirstId (arr) {
  if (!arr?.[0]) return ''
  return arr[0]?.children?.length ? getFirstAndFirstId(arr[0].children) : arr[0]
}

const getLev1Node = (nodeObj) => {
  return nodeObj?.parent?.parent ? getLev1Node(nodeObj.parent) : nodeObj.data
}

// 节点点击事件（保持单选高亮）
const nodeClick = (node, nodeObj) => {
  const id = node.id;
  nodeobj.id = node.id
  const lev1 = getLev1Node(nodeObj)

  // 保持当前节点的高亮显示
  emits("update:modelValue", id);
  emits("change", id, node, lev1);
};
// 展开选中节点的所有父节点路径
const expandSelectedNodesPaths = (nodeIds) => {
  if (!treeRef.value || !nodeIds.length) return;

  const expandedKeys = new Set([...expandKeys.value]);

  nodeIds.forEach(nodeId => {
    const node = treeRef.value.getNode(nodeId);
    if (node) {
      // 展开该节点的所有父节点
      let parent = node.parent;
      while (parent && parent.level > 0) {
        expandedKeys.add(parent.data.id);
        // 同时设置节点的 expanded 状态
        parent.expanded = true;
        parent = parent.parent;
      }
    }
  });

  // 更新展开的节点
  expandKeys.value = Array.from(expandedKeys);
};
// 勾选事件处理
const handleCheck = (checkedNode, checkedNodes) => {
  // 获取所有选中的节点
  const checkedKeys = treeRef.value.getCheckedKeys();

  // 过滤出叶子节点（没有子节点的节点）
  const leafCheckedKeys = checkedKeys.filter(key => {
    const node = treeRef.value.getNode(key);
    return node && (!node.data.children || node.data.children.length === 0);
  });

  // 重新设置只选中叶子节点
  treeRef.value.setCheckedKeys(leafCheckedKeys);

  // 获取对应的叶子节点数据
  selectedNodes.value = leafCheckedKeys.map(key => {
    const node = treeRef.value.getNode(key);
    return node.data;
  });
};
const handleClose = () => {
  emits("dialogshow", false);
};

const handleSave = () => {
  // 保存时传递所有选中的节点
  if (selectedNodes.value.length > 0) {
    emits("save", selectedNodes.value, selectedLev1Nodes.value);
  } else {
    // 如果没有勾选任何节点，可以提示用户或传递空数组
    ElMessage.warning('请至少选择一个风险单元');
    return; // 不关闭弹窗
  }
  emits("dialogshow", false);
};

// 修改获取树数据的方法
function getTreeData () {
  getApi({}, '/mosty-jcgl/fxdy/tree').then(async (res) => {
    if (res) {
      treeData.value = Array.isArray(res) ? res : [];
      expandKeys.value = getExpandFirstArr(treeData.value, []);

      // 等待 DOM 更新
      nextTick(() => {
        // 如果已经有选中的数据，设置选中状态
        if (props.selectedData && props.selectedData.length > 0 && !hasSetSelectedNodes.value) {
          setSelectedNodes(props.selectedData);
          hasSetSelectedNodes.value = true;
        } else {
          // 如果没有选中的数据，设置默认第一个节点
          const firstItem = getFirstAndFirstId(treeData.value);
          if (firstItem) {
            nodeobj.id = firstItem.id;
            const lev1 = treeData.value[0];
            if (treeRef.value) {
              treeRef.value.setCurrentKey(firstItem.id);
            }
            emits("update:modelValue", firstItem.id);
            emits("change", firstItem.id, firstItem, lev1);
          }
        }
      });
    }
  });
}
// 监听 selectedData 的逻辑
watch(() => props.selectedData, (newVal) => {
  // 如果树数据已经加载，立即设置选中状态
  if (newVal && newVal.length > 0 && treeData.value.length > 0) {
    setSelectedNodes(newVal);
    hasSetSelectedNodes.value = true;
  }
  // 如果树数据还没加载，会在 getTreeData 中处理
}, { immediate: true });

// 修改弹窗打开监听
watch(() => props.showdialog, (newVal) => {
  if (newVal && treeRef.value) {
    // 弹窗打开时，重新设置选中状态
    const currentNodes = props.selectedData.length > 0 ? props.selectedData : selectedNodes.value;
    if (currentNodes && currentNodes.length > 0) {
      // 使用 setTimeout 确保 DOM 完全渲染
      setTimeout(() => {
        const keysToCheck = currentNodes.map(node => node.id);
        treeRef.value.setCheckedKeys(keysToCheck);
        
        // 新增：展开选中节点的路径
        expandSelectedNodesPaths(keysToCheck);
        
        // 设置高亮显示第一个节点
        if (currentNodes[0]) {
          treeRef.value.setCurrentKey(currentNodes[0].id);
        }
      }, 100);
    }
  }
});
// setSelectedNodes 方法
const setSelectedNodes = (selectedData) => {
  if (selectedData && selectedData.length > 0 && treeRef.value) {
    // 提取 node 对象数组
    const nodes = selectedData.map(item => item.node);
    selectedNodes.value = nodes;
    // 提取所有节点的 ID
    const keysToCheck = nodes.map(node => node.id);
    try {
      treeRef.value.setCheckedKeys(keysToCheck);

      // 新增：展开选中节点的路径
      expandSelectedNodesPaths(keysToCheck);

      // 设置高亮显示第一个节点
      if (nodes[0]) {
        nodeobj.id = nodes[0].id;
        treeRef.value.setCurrentKey(nodes[0].id);
      }
    } catch (error) {
    }
  }
};

// 暴露方法给父组件
defineExpose({
  setSelectedNodes,
});
</script>

<style lang="scss" scoped>
.depar_hear {
  height: 32px;
}

.prefix {
  margin-right: 5px;
}

.depar_foot {
  // overflow: auto;
}

.departmentTree-box {
  height: 80vh;
}
</style>
