<template>
  <div>
    <div>
      <el-input placeholder="住院号/姓名" v-model="searchKey" @keyup.enter="handleSearch">
        <template #append>
          <el-button icon="Search" @click="handleSearch" />
        </template>
      </el-input>
    </div>
    <el-tree
      ref="treeRef"
      :key="treeKey"
      :load="loadNode"
      lazy
      show-checkbox
      node-key="id"
      default-expand-all
      :props="{ label: 'name', children: 'children' }"
      @node-click="handleNodeClick"
      @check="handleCheckChange"
    >
      <template #default="{ node, data }">
        <div class="custom-tree-node" v-if="node.level === 2">
          <span>{{ data.bedName + ' / ' + node.label }}</span>
          <span class="tree-node-actions">
            {{ data.genderEnum_enumText + ' / ' + data.age }}
          </span>
        </div>
      </template>
    </el-tree>
  </div>
</template>

<script setup>
import { getPatientList, getWardList } from './api';
import { updatePatientInfoList } from './store/patient';
import { ref, nextTick, inject, defineExpose } from 'vue';

const treeRef = ref(null);
const searchKey = ref('');
const treeKey = ref(0); // 用于强制重新渲染树组件
const wardList = ref([]); // 存储病区列表
const patientDataCache = ref(new Map()); // 缓存患者数据：key为wardId，value为患者列表

const handleGetPrescription = inject('handleGetPrescription');

/**
 * 加载树节点数据
 * @param {Object} node - 树节点对象
 * @param {Function} resolve - 解析函数，用于返回子节点数据
 */
function loadNode(node, resolve) {
  // 根节点：加载所有病区
  if (node.level === 0) {
    loadWardList(resolve);
  }
  // 病区节点：加载该病区下的患者列表
  else if (node.level === 1) {
    const wardId = node.data.id;
    loadPatientList(wardId, resolve);
  }
  // 其他层级返回空数组
  else {
    resolve([]);
  }
}

/**
 * 加载病区列表
 * @param {Function} resolve - 解析函数
 */
function loadWardList(resolve) {
  getWardList()
    .then((res) => {
      // 格式化病区数据
      const wards = Array.isArray(res) ? res : res.data || [];
      wardList.value = wards;

      // 将病区数据转换为树节点格式
      const wardNodes = wards.map((ward) => ({
        id: ward.id,
        name: ward.name || ward.wardName || '',
        leaf: false, // 病区节点不是叶子节点
        ...ward,
      }));

      resolve(wardNodes);
    })
    .catch((error) => {
      console.error('加载病区列表失败:', error);
      resolve([]);
    });
}

/**
 * 加载指定病区的患者列表
 * @param {String|Number} wardId - 病区ID
 * @param {Function} resolve - 解析函数
 */
function loadPatientList(wardId, resolve) {
  // 构建缓存键（包含搜索条件）
  const cacheKey = `${wardId}_${searchKey.value || ''}`;

  // 如果缓存中存在且搜索条件为空，直接使用缓存（搜索时需要重新加载）
  if (!searchKey.value && patientDataCache.value.has(cacheKey)) {
    const cachedPatients = patientDataCache.value.get(cacheKey);
    resolve(cachedPatients);
    return;
  }

  // 调用接口获取患者列表
  getPatientList({
    wardId: wardId,
    searchKey: searchKey.value || '',
  })
    .then((res) => {
      // 处理返回的患者数据
      const records = res?.data?.records || [];

      // 格式化患者数据
      const patients = records.map((item) => ({
        id: item.id || item.encounterId,
        name: item.patientName || '',
        leaf: true, // 患者节点是叶子节点
        ...item,
      }));

      // 缓存患者数据（仅在没有搜索条件时缓存）
      if (!searchKey.value) {
        patientDataCache.value.set(cacheKey, patients);
      }

      resolve(patients);
    })
    .catch((error) => {
      console.error('加载患者列表失败:', error);
      resolve([]);
    });
}

/**
 * 重新加载所有病区的患者列表
 */
function reloadAllPatients() {
  if (!treeRef.value) return;

  // 清除患者数据缓存
  patientDataCache.value.clear();

  nextTick(() => {
    const rootNode = treeRef.value?.store?.root;
    if (!rootNode?.childNodes) return;

    // 遍历所有已展开的病区节点，重新加载患者列表
    rootNode.childNodes.forEach((wardNode) => {
      if (wardNode && wardNode.level === 1 && wardNode.key) {
        reloadWardNodePatients(wardNode);
      }
    });
  });
}

/**
 * 重新加载指定病区节点的患者列表
 * @param {Object} wardNode - 病区节点对象
 */
function reloadWardNodePatients(wardNode) {
  if (!wardNode?.key || !treeRef.value) return;

  const wardId = wardNode.data.id;
  const cacheKey = `${wardId}_${searchKey.value || ''}`;

  // 清除该病区的缓存
  patientDataCache.value.delete(cacheKey);

  // 清除旧的子节点
  treeRef.value.updateKeyChildren(wardNode.key, []);

  // 重置节点状态
  wardNode.loaded = false;
  wardNode.childNodes = [];

  // 重新加载患者列表
  loadPatientList(wardId, (children) => {
    treeRef.value.updateKeyChildren(wardNode.key, children);
  });
}

/**
 * 重新加载指定病区的患者列表
 * @param {String|Number} wardId - 病区ID
 */
function reloadWardPatients(wardId) {
  if (!treeRef.value) return;

  nextTick(() => {
    const rootNode = treeRef.value?.store?.root;
    if (!rootNode?.childNodes) return;

    // 查找对应的病区节点
    const wardNode = rootNode.childNodes.find((node) => node.data.id === wardId);
    if (wardNode) {
      reloadWardNodePatients(wardNode);
    }
  });
}

/**
 * 手动触发加载节点
 * @param {Object} node - 节点对象，如果为null则重新加载整个树
 */
function manualLoadNode(node = null) {
  if (!node) {
    // 重新加载整个树
    treeKey.value += 1;
    patientDataCache.value.clear();
  } else if (node.key && treeRef.value) {
    // 重新加载指定节点
    if (node.level === 1) {
      // 病区节点：重新加载患者列表
      reloadWardNodePatients(node);
    } else if (node.level === 0) {
      // 根节点：重新加载病区列表
      loadWardList((wards) => {
        treeRef.value.updateKeyChildren(node.key, wards);
      });
    }
  }
}

/**
 * 获取所有选中的叶子节点（患者节点）
 * @returns {Array} 患者节点数组
 */
function getCheckedLeafNodes() {
  if (!treeRef.value) return [];

  // 获取所有选中的节点数据
  const checkedNodes = treeRef.value.getCheckedNodes() || [];

  // 只返回叶子节点（患者节点）
  return checkedNodes.filter((node) => node.leaf === true);
}

/**
 * 处理节点选中状态变化
 * @param {Object} data - 节点数据
 * @param {Object} checked - 选中状态对象
 */
function handleCheckChange(data, checked) {
  const checkedPatients = getCheckedLeafNodes();
  updatePatientInfoList(checkedPatients);

  // 调用父组件的方法获取处方列表
  if (handleGetPrescription && typeof handleGetPrescription === 'function') {
    handleGetPrescription();
  }
}

/**
 * 处理节点点击事件
 * @param {Object} data - 节点数据
 * @param {Object} node - 节点对象
 */
function handleNodeClick(data, node) {
  // 节点点击处理逻辑（可根据需要添加）
}

/**
 * 处理搜索
 */
function handleSearch() {
  // 清除缓存（搜索时需要重新加载）
  patientDataCache.value.clear();

  // 重新加载所有已展开病区的患者列表
  reloadAllPatients();
}

// 暴露方法供外部调用
defineExpose({
  manualLoadNode,
  reloadAllPatients,
  reloadWardPatients,
  handleSearch,
});
</script>

<style scoped lang="scss">
.custom-tree-node {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
}

.tree-node-actions {
  display: flex;
  align-items: center;
}

:deep(.el-tree-node__content) {
  height: 35px;
}
</style>