<template>
  <div class="comp-content">
    <div class="content">
      <DragSplit :hideLeft="hideTree" :leftContentWidth="400">
        <template #left>
          <div class="left-content">
            <div class="options">
              <slot name="options" />
            </div>
            <div class="tree-data">
              <el-tree
                v-if="visible"
                ref="treeRef"
                :node-key="dataKey.id"
                highlight-current
                :load="loadMoreFun"
                lazy
                :props="{
                  label: dataKey.name,
                  children: 'children',
                  isLeaf: 'leaf',
                }"
                @node-click="nodeClickFun"
                @current-change="currentChangeFun"
              >
                <template #default="{ data, node }">
                  <div class="tree-item">
                    <div class="icon">
                      <template v-if="data.dataType === 1">
                        <el-icon :size="18">
                          <Folder v-if="!node.expanded" />
                          <FolderOpened v-else />
                        </el-icon>
                      </template>
                      <template v-if="data.dataType === 2">
                        <el-icon :size="18">
                          <Document />
                        </el-icon>
                      </template>
                    </div>
                    <div class="label" :title="data[dataKey.name]">{{ data[dataKey.name] }}</div>
                    <div class="actions">
                      <slot name="treeAction" :data="data" :node="node" />
                    </div>
                  </div>
                </template>
              </el-tree>
            </div>
          </div>
        </template>
        <template #right>
          <div class="right-content">
            <div class="top-content">
              <div class="menu">
                <el-breadcrumb separator="/">
                  <el-breadcrumb-item
                    v-for="item in navList"
                    :key="item[dataKey.id]"
                    @click="openDirFun(item[dataKey.id])"
                  >
                    <span class="bread-item">{{ item[dataKey.name] }}</span>
                  </el-breadcrumb-item>
                </el-breadcrumb>
              </div>
            </div>
            <div class="table">
              <slot name="table" />
            </div>
          </div>
        </template>
      </DragSplit>
    </div>
  </div>
</template>

<script lang="ts" setup>
import { ref } from 'vue';
import { Folder, FolderOpened, Document } from '@element-plus/icons-vue';
import DragSplit from '@/components/common/dragSplit/index.vue';

interface Props {
  api: any;
  hideTree?: boolean;
  dataKey?: any;
  param?: any;
}

const props = withDefaults(defineProps<Props>(), {
  api: null,
  hideTree: false,
  dataKey: {
    id: 'id',
    pId: 'parentDirId',
    name: 'originalName',
  },
  param: {},
});

const emit = defineEmits(['choseNode', 'updateNav']);

const treeRef = ref<any>();
const navList = ref<any>([]);
const visible = ref(true);

// 加载节点
const loadMoreFun = async (node: any, resolve: any) => {
  const listData: any = await getDataFun(node.data[props.dataKey.id] || '');
  if (node.level >= 1) {
    node.data.children = listData;
    choseNodeFun(node.data);
  }
  return resolve(listData);
};

// 获取节点数据
const getDataFun = async (pId: string) => {
  if (props.api) {
    const params: any = { ...props.param };
    params[props.dataKey.pId] = pId || '';
    const res: any = await props.api(params);
    if (res.code === 200) {
      return res.data;
    } else {
      return [];
    }
  }
};

// 树形节点点击
const nodeClickFun = (data: any, node: any) => {
  updateNavFun([]);
  getTreeMenuFun(node);
  choseNodeFun(data);
};

// 循环获取父节点
const getTreeMenuFun = (node: any) => {
  if (node.label && node.parent) {
    const data = navList.value;
    data.unshift(node.data);
    updateNavFun(data);
    getTreeMenuFun(node.parent);
  }
};

// 打开目录
const openDirFun = (id: any) => {
  const node = treeRef.value.getNode(String(id));
  if (node) {
    node.loaded = false;
    node.expand();
    treeRef.value.setCurrentKey(id);
    choseNodeFun(node.data);
  }
};

// 返回上一级
const backFun = () => {
  const data = navList.value[navList.value.length - 2];
  openDirFun(data[props.dataKey.id]);
};

// 当前节点更改
const currentChangeFun = (data: any, node: any) => {
  updateNavFun([]);
  getTreeMenuFun(node);
};

// 选中节点
const choseNodeFun = (data: any) => {
  emit('choseNode', data);
};

// 导航变更
const updateNavFun = (data: any) => {
  navList.value = data;
  emit('updateNav', data);
};

const reloadFun = () => {
  visible.value = false;
  setTimeout(() => {
    visible.value = true;
  }, 0);
};

defineExpose({
  backFun,
  openDirFun,
  reloadFun,
});
</script>

<style lang="scss" scoped>
.comp-content {
  height: 100%;
  .content {
    position: relative;
    height: 100%;
    display: flex;
    .left-content {
      width: 100%;
      min-height: 100%;
      background-color: var(--el-bg-color);
      border-radius: var(--border-radius-normal);
      padding: var(--padding-normal);
      .tree-item {
        width: calc(100% - 24px);
        height: 100%;
        display: flex;
        .icon {
          display: flex;
          align-items: center;
          justify-content: center;
          width: 26px;
          color: var(--el-color-primary);
        }
        .label {
          flex: 1;
          line-height: 26px;
          white-space: nowrap;
          overflow: hidden;
          text-overflow: ellipsis;
        }
        .actions {
          display: flex;
          align-items: center;
          padding-left: var(--padding-normal);
        }
      }
    }
    .right-content {
      display: flex;
      flex-direction: column;
      width: 100%;
      height: 100%;
      background-color: var(--el-bg-color);
      border-radius: var(--border-radius-normal);
      padding: 0 var(--padding-normal) var(--padding-normal);
      .top-content {
        display: flex;
        align-items: center;
        padding: 10px 0;
        margin-bottom: 10px;
        border-bottom: solid 1px var(--el-border-color-light);
        .menu {
          flex: 1;
          min-height: 24px;
          margin-right: 20px;
          border-radius: 4px;
          display: flex;
          align-items: center;
          padding: 5px 10px;
          .bread-item {
            color: var(--el-color-primary);
          }
        }
        .search {
          height: 24px;
          background-color: var(--el-bg-color-page);
          border-radius: 4px;
          display: flex;
          align-items: center;
        }
      }
      .table {
        flex: 1;
        height: 0;
      }
    }
  }
}
</style>
