<template>
  <div class="comp-content">
    <div class="content">
      <div v-if="!hideTree" class="left-content" :class="{ hide: !isToggleShow }">
        <div class="options">
          <slot name="options" />
        </div>
        <div class="tree-data">
          <el-tree
            v-if="visible"
            ref="treeRef"
            node-key="id"
            highlight-current
            :load="loadMoreFun"
            lazy
            :props="{
              label: 'originalName',
              children: 'children',
              isLeaf: 'leaf',
            }"
            v-bind="$attrs"
            @node-click="nodeClickFun"
            @current-change="currentChangeFun"
          >
            <template #default="{ data, node }">
              <div class="tree-item">
                <div class="name">
                  <div class="icon">
                    <el-icon :size="18">
                      <MessageBox v-if="data.relatedResourceUuidOwnType === NODE_TYPE.PROJECT" />
                      <Share v-else-if="data.relatedResourceUuidOwnType === NODE_TYPE.PHASE" />
                      <Document v-else-if="data.relatedResourceUuidOwnType === NODE_TYPE.TASK" />
                      <Folder v-else />
                    </el-icon>
                  </div>
                  <div class="label">{{ data.originalName }}</div>
                </div>
                <div class="actions">
                  <slot name="treeAction" :data="data" :node="node" />
                </div>
              </div>
            </template>
          </el-tree>
        </div>
      </div>
      <div class="toggle-btn" :class="{ hide: !isToggleShow }" @click="toggleFun">
        <el-icon :size="12">
          <DArrowLeft />
        </el-icon>
      </div>
      <div class="right-content">
        <div class="top-content">
          <div class="menu">
            <el-breadcrumb separator="/">
              <el-breadcrumb-item v-for="item in navList" :key="item.id" @click="openDirFun(item.id)">
                {{ item.originalName }}
              </el-breadcrumb-item>
            </el-breadcrumb>
          </div>
          <div class="search" @click="searchFun">
            <el-input v-model="searchData" :suffix-icon="Search" placeholder="搜索" size="small" clearable />
          </div>
        </div>
        <div class="table">
          <slot name="table" />
        </div>
      </div>
    </div>
  </div>
</template>

<script lang="ts" setup>
import { ref, watch } from 'vue';
import { MessageBox, Share, Folder, DArrowLeft, Search, Document } from '@element-plus/icons-vue';
import { NODE_TYPE } from '@/utils/enum/node';

interface Props {
  api: any;
  hideTree?: boolean;
  templateId: number;
}

const props = withDefaults(defineProps<Props>(), {
  api: null,
  hideTree: false,
  templateId: 0,
});

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

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

watch(
  () => props.templateId,
  () => {
    reloadFun();
  }
);

// 加载节点
const loadMoreFun = async (node: any, resolve: any) => {
  const listData: any = await getDataFun(node.data);
  if (node.level >= 1) {
    listData.forEach((item: any) => {
      item.relatedParentUuid = node.data.relatedResourceUuid;
    });
    node.data.children = listData;
    choseNodeFun(node.data);
  }
  return resolve(listData);
};

// 获取节点数据
const getDataFun = async (data: any) => {
  if (props.api) {
    const params = {
      dimensionTemplateId: props.templateId,
      fileId: data.id || '',
    };
    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.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 = () => {
  navList.value = [];
  visible.value = false;
  setTimeout(() => {
    visible.value = true;
  }, 0);
};

const toggleFun = () => {
  isToggleShow.value = !isToggleShow.value;
};

const searchFun = () => {
  emit('search');
};

const reloadNodeFun = (id: any) => {
  const node = treeRef.value.getNode(id);
  if (node) {
    node.loaded = false;
    node.expand();
  }
};

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

<style lang="scss" scoped>
.comp-content {
  height: 100%;
  .content {
    position: relative;
    height: 100%;
    display: flex;
    .toggle-btn {
      position: absolute;
      display: flex;
      justify-content: center;
      align-items: center;
      top: 50%;
      left: 400px;
      margin-top: -20px;
      background-color: var(--el-bg-color);
      border-radius: 0 4px 4px 0;
      width: 14px;
      height: 40px;
      border: solid 1px var(--el-border-color-darker);
      border-left: 0;
      color: var(--el-text-color-regular);
      cursor: pointer;
      transition: all 0.3s;
      &.hide {
        left: -14px;
        transform: rotateZ(180deg);
      }
    }
    .left-content {
      width: 400px;
      overflow: auto;
      margin-right: var(--margin-normal);
      background-color: var(--el-bg-color);
      border-radius: var(--border-radius-normal);
      padding: var(--padding-normal);
      border-right: solid 1px var(--el-border-color-darker);
      transition: all 0.3s;
      &.hide {
        width: 0;
        padding: 0;
        margin: 0;
      }
      .tree-item {
        flex: 1;
        display: flex;
        align-items: center;
        justify-content: space-between;
        min-height: 20px;
        width: 0;
        .name {
          flex: 1;
          display: flex;
          align-items: center;
          overflow: hidden;
          text-overflow: ellipsis;
          .icon {
            display: flex;
            align-items: center;
            justify-content: center;
            width: 20px;
            height: 20px;
            margin-right: var(--margin-tiny);
          }
          .label {
            display: flex;
            align-items: center;
            min-height: 20px;
          }
        }
        .actions {
          padding-left: var(--padding-normal);
          display: flex;
          align-items: center;
          min-height: 20px;
        }
      }
    }
    .right-content {
      flex: 1;
      overflow: auto;
      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;
          height: 24px;
          background-color: var(--el-bg-color-page);
          margin-right: 20px;
          border-radius: 4px;
          display: flex;
          align-items: center;
          padding: 0 10px;
        }
        .search {
          height: 24px;
          background-color: var(--el-bg-color-page);
          border-radius: 4px;
          display: flex;
          align-items: center;
        }
      }
    }
  }
}
</style>
