<template>
  <a-tree :treeData="treeData" :expandedKeys="expandedKeys" :selectedKeys="selectedKeys" @expand="handleExpand" @select="handleSelect"></a-tree>
</template>

<script>
import { Tree } from 'ant-design-vue'
import Vue from 'vue'
import { getConfig, runLogic } from '@vue2-client/services/api/common'

export default {
  components: {
    'a-tree': Tree,
  },
  props: {
    configContent: {
      type: Object,
      default: () => {}
    },
    systemName: {
      type: String,
      default: ''
    },
    configName: {
      type: String,
      default: ''
    },
  },
  data () {
    return {
      treeData: [],
      expandedKeys: [],
      selectedKeys: [],
      actualConfig: null,
    }
  },
  async mounted () {
    try {
      this.actualConfig = await getConfig(this.configContent, this.configName, this.systemName)
    } catch (error) {
      console.error('Failed to get config:', error)
    }
    // 根据配置文件中的tableStructure字段生成树组件结构
    this.generateTreeData()
  },
  methods: {
    async generateTreeData () {
      try {
        // 定义逻辑名称和参数，这里需要根据实际情况来填写
        const logicName = 'get_root_nodes' // 例如: 'GenerateTreeStructure'
        const parameters = {
          // 你需要传递给后端逻辑的参数
          // 例如: key1: 'value1', key2: 'value2'
        }

        // 调用通用业务逻辑函数
        const response = await runLogic(logicName, parameters)

        // 检查返回的数据是否有效，这将依赖于你的后端服务发送什么样的响应
        if (response && response.data) {
          // 如果响应中有数据，则将其设置为树组件的数据
          this.treeData = response.data // 或者根据实际的返回结构调整，比如 response.data.treeStructure
        } else {
          // 处理没有返回数据的情况，可以是设置默认值或抛出错误
          throw new Error('No data returned from the logic execution')
        }
      } catch (error) {
        // 处理调用逻辑或设置数据时出现的错误
        console.error('There was an error generating the tree data:', error)
        // 这里可以进行更多的错误处理，比如显示一个错误消息到UI界面
      }
    },
    async handleExpand (expandedKeys, { expanded, node }) {
      console.log('handleExpand', expandedKeys, expanded, node)
      // 更新展开的节点列表，由于这不依赖于异步操作，因此可以立即设置
      this.expandedKeys = expandedKeys

      if (expanded) {
        try {
          // 向后端发送请求，获取子节点数据
          const path = this.getNodePath(node)
          const childNodes = await this.fetchChildNodes(path) // 等待子节点数据

          // 将子节点数据添加到当前节点下
          Vue.set(node, 'children', childNodes)

          // 现在，我们需要确保每个子节点都有一个指向其父节点的引用。
          // 这是必须的，因为 'getNodePath' 方法依赖于 'parentNode' 属性来重建节点的完整路径。
          if (childNodes && childNodes.length) {
            childNodes.forEach(child => {
              // 由于我们直接修改了节点，这可能不会触发视图的自动更新。
              // 如果你遇到了这个问题，你可能需要找到一种方法来手动触发组件的重新渲染。
              child.parentNode = node
            })
          }
        } catch (error) {
          // 处理或记录错误
          console.error('An error occurred:', error)
          // 这里可以执行其他错误处理逻辑，比如向用户显示错误消息
        }
      }
      // 如果没有展开，就没有更多要做的，因为 this.expandedKeys 已经更新
    },
    handleSelect (selectedKeys, { selected, node }) {
      if (selected) {
        // 触发节点选中事件，传递节点的完整路径
        const path = this.getNodePath(node)
        this.$emit('nodeSelected', path)
      } else {
        this.selectedKeys = selectedKeys
      }
    },
    getNodePath (node) {
      // 获取节点的完整路径
      let path = node.title
      let parent = node.parentNode
      while (parent) {
        path = parent.title + '/' + path
        parent = parent.parentNode
      }
      return path
    },
    async fetchChildNodes (path) {
      // 定义逻辑名称和参数 - 根据你的后端逻辑具体定义这些值
      const logicName = 'get_child_nodes' // 例如，这可能是后端服务识别的逻辑名称
      const parameters = {
        path: path, // 参数是什么取决于你的后端服务需要什么
      }

      try {
        // 调用通用业务逻辑函数并等待结果
        const response = await runLogic(logicName, parameters)

        // 确保响应包含我们期望的数据 - 如果你的后端服务使用不同的结构，你可能需要调整这里
        if (response && response.data) {
          return Promise.resolve(response.data) // 返回子节点数据
        } else {
          // 如果响应格式不符合预期，可以抛出一个错误或返回一个失败的Promise
          // eslint-disable-next-line prefer-promise-reject-errors
          return Promise.reject('Received unexpected response format')
        }
      } catch (error) {
        // 如果请求失败（例如网络错误、服务器错误等），我们捕获这个错误并将其向上传递
        console.error('Error fetching child nodes:', error)
        return Promise.reject(error.message || 'Error fetching child nodes')
      }
    }
  },
}
</script>
