<template>
  <!-- 预览界面 -->
  <el-drawer v-model="preview.visible" title="编辑" :size="1200" :with-header="false">
    <el-row>
      <el-col :span="5">
        <el-tree
          ref="treeRef"
          style="max-width: 600px; margin-top: 1rem"
          :data="treeData"
          :props="{
            children: 'children',
            label: 'label'
          }"
          @node-click="handleNodeClick"
        />
      </el-col>
      <el-col :span="19">
        <el-tabs v-model="preview.activeName" @tab-click="handleTabClick">
          <el-tab-pane
            v-for="(item, key) in preview.data"
            :key="key"
            :label="item.fileName"
            :name="key"
          >
            <code-mirror
              v-model="item.content"
              height="calc(100vh - 40px - 40px - 15px)"
            ></code-mirror>
          </el-tab-pane>
        </el-tabs>
      </el-col>
    </el-row>
  </el-drawer>
</template>

<script setup lang="ts">
import { reactive, ref, onMounted, nextTick } from 'vue'
import { ElLoading } from 'element-plus'
import { usePreviewApi } from '@/api/generator'
import CodeMirror from '@/components/codemirror/CodeMirror.vue'

const treeRef = ref(null)
const preview = reactive({
  visible: false,
  title: '代码预览',
  data: {},
  activeName: ref(0)
})

const init = async (tableId?: number) => {
  const loadingInstance = ElLoading.service({ fullscreen: true })
  try {
    let resData = await usePreviewApi(tableId)
    preview.activeName = 0
    preview.data = resData.data.map((item: previewItem) => {
      item.fileName = item.path.split('/').slice(-1)[0].split('\\').slice(-1)[0]
      return item
    })
    treeData.value = pathsToElTree(preview.data.map(item => item.path))
    preview.visible = true
    await nextTick()
    expandAllNodes()
  } finally {
    loadingInstance.close()
  }
}

interface TreeNode {
  id: string
  label: string
  path: string
  children: TreeNode[]
}

interface previewItem {
  path: string
  fileName: string
  content: string
}

const treeData = ref<TreeNode[]>()

function insertPathIntoTree(
  tree: TreeNode[],
  parts: string[],
  path: string,
  index: number = 0
): void {
  if (index >= parts.length) {
    return
  }
  const part = parts[index]
  let node = tree.find(n => n.label === part)
  if (!node) {
    node = {
      id: part,
      label: part,
      path: path,
      children: []
    }
    tree.push(node)
  }
  insertPathIntoTree(node.children, parts, path, index + 1)
}

function pathsToElTree(paths: string[]): TreeNode[] {
  const tree: TreeNode[] = []
  paths.forEach(path => {
    const parts = path.split(/[\\/]/)
    insertPathIntoTree(tree, parts, path)
  })
  return tree
}

const handleNodeClick = (node: TreeNode) => {
  const targetTab = preview.data.findIndex(item => item.path === node.path)
  if (targetTab !== -1) {
    preview.activeName = targetTab
  }
  // 展开两级节点
  const tree = treeRef.value
  if (tree) {
    const store = tree.store
    const nodeModel = store.getNode(node.id)
    if (nodeModel) {
      nodeModel.expanded = true
      if (nodeModel.childNodes) {
        nodeModel.childNodes.forEach(child => {
          child.expanded = true
          if (child.childNodes) {
            child.childNodes.forEach(grandChild => {
              grandChild.expanded = true
            })
          }
        })
      }
    }
  }
}

const handleTabClick = (tab: { label: string }) => {
  const targetNode = findNodeInTree(treeData.value || [], tab.label)
  if (targetNode) {
    // 这里假设 el-tree 有展开节点的方法，具体方法名可能需要根据 el-tree 的实际 API 来调整
    // 例如：展开节点的方法可能是 expand(node)，这里只是示例
    // expand(targetNode)
  }
}

function findNodeInTree(tree: TreeNode[], label: string): TreeNode | null {
  for (const node of tree) {
    if (node.label === label) {
      return node
    }
    const childNode = findNodeInTree(node.children, label)
    if (childNode) {
      return childNode
    }
  }
  return null
}

const expandAllNodes = () => {
  const tree = treeRef.value
  if (tree) {
    const store = tree.store
    const rootNodes = store.root.childNodes
    const expandNode = node => {
      node.expanded = true
      if (node.childNodes) {
        node.childNodes.forEach(child => {
          expandNode(child)
        })
      }
    }
    rootNodes.forEach(rootNode => {
      expandNode(rootNode)
    })
  }
}

onMounted(() => {
  expandAllNodes()
})

defineExpose({
  init
})
</script>
