<template>
  <div class="tree-container">
    <div class="tree-header">
      <el-button v-hasPermi="['document:folder:add']" type="primary" icon="Plus" size="small" @click="handleAddFolder">
        {{ t('document.document.button.newFolder') }}
      </el-button>
    </div>
    <el-scrollbar class="tree-scrollbar">
      <el-tree ref="treeRef" v-loading="loading" :data="treeData" :props="treeProps" node-key="id" :expand-on-click-node="false">
        <template #default="{ node, data }">
          <span class="custom-tree-node">
            <el-icon>
              <Folder v-if="data.type === 0" />
              <Location v-else-if="data.type === 1" />
              <OfficeBuilding v-else-if="data.type === 2" />
              <Document v-else />
            </el-icon>
            <span class="node-label" @click="handleFolderClick(data)">{{ node.label }}</span>
            <el-badge v-if="data.id === 0 && tempDocumentCount > 0" :value="tempDocumentCount" type="danger" class="temp-badge" />
            <span v-if="data.id !== 0" class="node-actions">
              <span class="menu-trigger" @click="toggleMenu($event, data)">
                <el-icon>
                  <MoreFilled />
                </el-icon>
              </span>
            </span>
          </span>
        </template>
      </el-tree>
    </el-scrollbar>

    <!-- 一级菜单 -->
    <ul class="primary-menu" v-if="activeMenu !== null" :style="primaryMenuStyle">
      <li class="menu-item has-submenu" @click.stop="toggleSubmenu($event)">
        <span>{{ t('document.document.menu.add') }}</span>
        <el-icon class="arrow-icon">
          <ArrowRight />
        </el-icon>
      </li>
      <li class="menu-item" v-hasPermi="['document:folder:edit']" @click="handleMenuItemClick('edit', currentMenuData)">
        <span>{{ t('document.document.menu.edit') }}</span>
      </li>
      <li class="menu-item" v-hasPermi="['document:folder:remove']" @click="handleMenuItemClick('delete', currentMenuData)">
        <span>{{ t('document.document.menu.delete') }}</span>
      </li>
    </ul>

    <!-- 二级菜单 -->
    <ul class="secondary-menu" v-if="showSecondaryMenu" :style="secondaryMenuStyle">
      <!-- 国家或中心：显示中心和文件夹 -->
      <template v-if="currentMenuData && (currentMenuData.type === 1 || currentMenuData.type === 2)" v-hasPermi="['document:folder:add']">
        <li class="menu-item" @click="handleMenuItemClick('add:2', currentMenuData)" v-hasPermi="['document:folder:add']">
          <span>{{ t('document.document.menu.center') }}</span>
        </li>
        <li class="menu-item" @click="handleMenuItemClick('add:0', currentMenuData)" v-hasPermi="['document:folder:add']">
          <span>{{ t('document.document.menu.folder') }}</span>
        </li>
      </template>
      <!-- 文件夹：只显示文件夹和文档 -->
      <template v-else-if="currentMenuData && currentMenuData.type === 0">
        <li class="menu-item" @click="handleMenuItemClick('add:0', currentMenuData)" v-hasPermi="['document:folder:add']">
          <span>{{ t('document.document.menu.folder') }}</span>
        </li>
        <li class="menu-item" v-hasPermi="['document:document:add']" @click="handleMenuItemClick('add:document', currentMenuData)">
          <span>{{ t('document.document.menu.document') }}</span>
        </li>
      </template>
    </ul>

    <!-- 文件夹表单对话框 -->
    <FolderFormDialog ref="folderFormDialogRef" @success="handleFolderFormSuccess" />

    <!-- 新增文档对话框 -->
    <AddDocumentDialog
      ref="addDocumentDialogRef"
      :project-id="projectId"
      :folder-id="currentDocumentFolderId"
      :document-info="currentDocumentInfo"
      @success="handleDocumentSuccess"
    />
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, onMounted, onUnmounted, nextTick, getCurrentInstance } from 'vue';
import { useI18n } from 'vue-i18n';
import { listFolder, delFolder, getNameByProjectId } from '@/api/document/folder';
import { FolderListVO } from '@/api/document/folder/types';
import { countTempDocuments } from '@/api/document/document';
import { Folder, Document, Location, OfficeBuilding, MoreFilled, ArrowRight } from '@element-plus/icons-vue';
import { ElMessage, ElMessageBox } from 'element-plus';
import type { ComponentInternalInstance } from 'vue';
import AddDocumentDialog from './components/AddDocumentDialog.vue';
import FolderFormDialog from './components/FolderFormDialog.vue';

interface Props {
  projectId?: number | string;
}

const props = defineProps<Props>();

const emit = defineEmits<{
  folderClick: [folder: FolderListVO];
  refresh: [];
}>();

const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const { t } = useI18n();

// 对话框引用
const folderFormDialogRef = ref<InstanceType<typeof FolderFormDialog>>();
const addDocumentDialogRef = ref<InstanceType<typeof AddDocumentDialog>>();

// 新增文档对话框相关
const currentDocumentFolderId = ref<number>();
const currentDocumentInfo = ref<{ projectCode: string; countryName: string; centerId: number | string }>();

// 数据定义
const loading = ref(false);
const treeData = ref<FolderListVO[]>([]);
const treeRef = ref();
const tempDocumentCount = ref(0);

// 树形组件配置
const treeProps = {
  children: 'children',
  label: 'name'
};

// 菜单状态管理
const activeMenu = ref<string | number | null>(null);
const showSecondaryMenu = ref(false);
const primaryMenuStyle = ref<any>({});
const secondaryMenuStyle = ref<any>({});
const currentMenuData = ref<FolderListVO | null>(null);

// 获取文件夹列表
const getList = async () => {
  if (!props.projectId) {
    ElMessage.warning(t('document.document.message.projectIdNotExist'));
    return;
  }

  loading.value = true;
  try {
    // 保存当前展开的节点
    const expandedKeys = treeRef.value?.store?.nodesMap
      ? Object.keys(treeRef.value.store.nodesMap).filter((key) => treeRef.value.store.nodesMap[key].expanded)
      : [];

    const res = await listFolder({ projectId: props.projectId } as any);
    const folders = res.data || [];

    // 添加临时文件夹到列表底部
    const tempFolder: FolderListVO = {
      id: 0,
      projectId: props.projectId as number,
      parentId: undefined,
      type: 0,
      name: '待归档区',
      status: 0,
      note: '',
      restrictionLevel: -1,
      children: []
    };

    treeData.value = [...folders, tempFolder];

    // 恢复展开状态
    nextTick(() => {
      if (expandedKeys.length > 0 && treeRef.value) {
        expandedKeys.forEach((key) => {
          const node = treeRef.value.store.nodesMap[key];
          if (node) {
            node.expanded = true;
          }
        });
      }
    });

    // 获取临时文件夹文档数量
    await getTempDocumentCount();
  } catch (error) {
    ElMessage.error(t('document.document.message.getFolderListFailed'));
    console.error(error);
  } finally {
    loading.value = false;
  }
};

// 获取临时文件夹文档数量
const getTempDocumentCount = async () => {
  if (!props.projectId) return;

  try {
    const res = await countTempDocuments(props.projectId);
    tempDocumentCount.value = res.data || 0;
  } catch (error) {
    console.error('获取临时文件夹数量失败:', error);
    tempDocumentCount.value = 0;
  }
};

// 新建文件夹（顶级）
const handleAddFolder = async () => {
  if (!props.projectId) {
    ElMessage.warning(t('document.document.message.projectIdNotExist'));
    return;
  }
  folderFormDialogRef.value?.open(props.projectId);
};

// 新增子节点（指定类型）
const handleAddChildWithType = async (data: FolderListVO, type: number) => {
  if (!props.projectId) {
    ElMessage.warning(t('document.document.message.projectIdNotExist'));
    return;
  }
  folderFormDialogRef.value?.open(props.projectId, data.id, type);
};

// 编辑
const handleEdit = async (data: FolderListVO) => {
  folderFormDialogRef.value?.openEdit(data.id);
};

// 处理文件夹表单成功
const handleFolderFormSuccess = async () => {
  await getList();
  emit('refresh');
};

// 删除
const handleDelete = async (data: FolderListVO) => {
  if (data.children && data.children.length > 0) {
    ElMessage.warning(t('document.document.message.hasChildren'));
    return;
  }

  try {
    await ElMessageBox.confirm(t('document.document.message.deleteConfirm', { name: data.name }), t('document.document.message.deleteTitle'), {
      confirmButtonText: t('document.document.message.confirmButton'),
      cancelButtonText: t('document.document.message.cancelButton'),
      type: 'warning'
    });

    loading.value = true;
    await delFolder(data.id);
    ElMessage.success(t('document.document.message.deleteSuccess'));
    await getList();
    emit('refresh');
  } catch (error: any) {
    if (error !== 'cancel') {
      console.error(t('document.document.message.deleteFailed'), error);
    }
  } finally {
    loading.value = false;
  }
};

// 切换菜单显示
const toggleMenu = async (event: MouseEvent, data: FolderListVO) => {
  if (event.type !== 'click') return;

  event.stopPropagation();
  event.preventDefault();

  const trigger = event.currentTarget as HTMLElement;
  const rect = trigger.getBoundingClientRect();

  if (activeMenu.value === data.id) {
    closeAllMenus();
  } else {
    // 在打开菜单时就获取文档信息
    await prepareDocumentInfo(data);

    primaryMenuStyle.value = {
      left: `${rect.left}px`,
      top: `${rect.bottom + 2}px`
    };

    activeMenu.value = data.id;
    currentMenuData.value = data;
    showSecondaryMenu.value = false;
  }
};

// 预先获取文档信息
const prepareDocumentInfo = async (data: FolderListVO) => {
  // 查找该文件夹所属的中心ID和国家名
  const centerId = findCenterId(data);
  const countryName = findCountryName(data);

  // 设置当前文件夹ID
  currentDocumentFolderId.value = data.id;

  const res = await getNameByProjectId(props.projectId);
  // 如果找到中心ID，调用接口获取项目编码
  if (centerId !== undefined) {
    try {
      // 设置文档信息
      currentDocumentInfo.value = {
        projectCode: res.data.projectCode,
        countryName: countryName || 'NA',
        centerId: centerId || 'NA'
      };
    } catch (error) {
      console.error('获取项目编码失败:', error);
      ElMessage.error('获取项目编码失败');
      // 即使失败也设置默认值
      currentDocumentInfo.value = {
        projectCode: '',
        countryName: countryName || 'NA',
        centerId: centerId || 'NA'
      };
    }
  } else {
    // 没有中心ID，使用默认值
    currentDocumentInfo.value = {
      projectCode: res.data.projectCode,
      countryName: countryName || 'NA',
      centerId: 'NA'
    };
  }
};

// 切换二级菜单显示
const toggleSubmenu = (event: MouseEvent) => {
  if (event.type !== 'click') return;

  event.stopPropagation();
  event.preventDefault();

  const target = event.currentTarget as HTMLElement;
  const rect = target.getBoundingClientRect();

  if (showSecondaryMenu.value) {
    showSecondaryMenu.value = false;
  } else {
    secondaryMenuStyle.value = {
      left: `${rect.right + 5}px`,
      top: `${rect.top}px`
    };

    nextTick(() => {
      showSecondaryMenu.value = true;
    });
  }
};

// 处理菜单项点击
const handleMenuItemClick = (command: string, data: FolderListVO | null) => {
  if (!data) return;

  handleCommand(command, data);
  closeAllMenus();
};

// 下拉菜单命令处理
const handleCommand = async (command: string, data: FolderListVO) => {
  if (command.startsWith('add:')) {
    const cmdPart = command.split(':')[1];
    if (cmdPart === 'document') {
      // 数据已经在toggleMenu时获取，直接打开对话框
      addDocumentDialogRef.value?.open();
    } else {
      const type = parseInt(cmdPart);
      handleAddChildWithType(data, type);
    }
  } else if (command === 'edit') {
    handleEdit(data);
  } else if (command === 'delete') {
    handleDelete(data);
  }
};

// 查找文件夹所属的中心ID
const findCenterId = (folder: FolderListVO): number | undefined => {
  // 如果当前节点就是中心，直接返回其ID
  if (folder.type === 2) {
    return folder.id;
  }

  // 如果有父节点ID，递归查找父节点
  if (folder.parentId !== undefined && folder.parentId !== null) {
    const parentFolder = findFolderById(treeData.value, folder.parentId);
    if (parentFolder) {
      return findCenterId(parentFolder);
    }
  }

  return undefined;
};

// 查找文件夹所属的国家名
const findCountryName = (folder: FolderListVO): string | undefined => {
  // 如果当前节点就是国家，直接返回其名称
  if (folder.type === 1) {
    return folder.name;
  }

  // 如果有父节点ID，递归查找父节点
  if (folder.parentId !== undefined && folder.parentId !== null) {
    const parentFolder = findFolderById(treeData.value, folder.parentId);
    if (parentFolder) {
      return findCountryName(parentFolder);
    }
  }

  return undefined;
};

// 根据ID查找文件夹
const findFolderById = (folders: FolderListVO[], id: number): FolderListVO | undefined => {
  for (const folder of folders) {
    if (folder.id === id) {
      return folder;
    }
    if (folder.children && folder.children.length > 0) {
      const found = findFolderById(folder.children, id);
      if (found) {
        return found;
      }
    }
  }
  return undefined;
};

// 点击文件夹节点
const handleFolderClick = (data: FolderListVO) => {
  emit('folderClick', data);
};

// 处理文档添加成功
const handleDocumentSuccess = () => {
  // 刷新树数据
  getList();
  // 通知父组件刷新文档列表
  emit('refresh');
};

// 关闭所有菜单
const closeAllMenus = () => {
  showSecondaryMenu.value = false;
  activeMenu.value = null;
  currentMenuData.value = null;
  primaryMenuStyle.value = {};
  secondaryMenuStyle.value = {};
};

// 点击页面其他地方关闭菜单
const handleClickOutside = (event: Event) => {
  if (!activeMenu.value && !showSecondaryMenu.value) return;

  const target = event.target as HTMLElement;
  const isClickInsideMenu = target.closest('.primary-menu') || target.closest('.secondary-menu') || target.closest('.menu-trigger');

  if (!isClickInsideMenu) {
    closeAllMenus();
  }
};

// 处理滚动事件
const handleScroll = () => {
  if (activeMenu.value || showSecondaryMenu.value) {
    closeAllMenus();
  }
};

// 暴露方法给父组件
defineExpose({
  getList,
  treeData,
  getTempDocumentCount
});

// 初始化
onMounted(() => {
  getList();
  document.addEventListener('click', handleClickOutside, true);
  document.addEventListener('scroll', handleScroll, true);
});

// 清理
onUnmounted(() => {
  document.removeEventListener('click', handleClickOutside, true);
  document.removeEventListener('scroll', handleScroll, true);
  closeAllMenus();
});
</script>

<style scoped lang="scss">
.tree-container {
  width: 400px;
  border-right: 1px solid #e4e7ed;
  display: flex;
  flex-direction: column;
}

.tree-header {
  padding: 10px;
  border-bottom: 1px solid #e4e7ed;
}

.tree-scrollbar {
  flex: 1;
  overflow: hidden;

  :deep(.el-scrollbar__view) {
    padding: 10px;
  }
}

.custom-tree-node {
  flex: 1;
  display: flex;
  align-items: center;
  font-size: 14px;
  padding-right: 8px;

  .el-icon {
    margin-right: 8px;
    font-size: 16px;
  }

  .node-label {
    flex: 1;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    cursor: pointer;

    &:hover {
      color: var(--el-color-primary);
    }
  }

  .temp-badge {
    margin-left: 8px;
    margin-right: 8px;
  }

  .node-actions {
    display: none;
    position: relative;
  }

  &:hover .node-actions {
    display: inline-flex;
    gap: 4px;
  }
}

.menu-trigger {
  cursor: pointer;
  display: flex;
  align-items: center;
  font-size: 16px;
  padding: 4px;
  border-radius: 4px;
  transition:
    background-color 0.3s,
    color 0.3s;

  &:hover {
    background-color: #f5f7fa;
    color: var(--el-color-primary);
  }
}

.primary-menu {
  position: fixed;
  min-width: 120px;
  background: #fff;
  border: 1px solid #e4e7ed;
  border-radius: 4px;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
  padding: 5px 0;
  margin: 0;
  list-style: none;
  z-index: 2000;

  .menu-item {
    padding: 8px 16px;
    cursor: pointer;
    font-size: 14px;
    color: #606266;
    transition:
      background-color 0.3s,
      color 0.3s;
    display: flex;
    justify-content: space-between;
    align-items: center;
    white-space: nowrap;

    &:hover {
      background-color: #f5f7fa;
      color: var(--el-color-primary);
    }

    &.has-submenu {
      .arrow-icon {
        margin-left: 8px;
        font-size: 12px;
      }
    }
  }
}

.secondary-menu {
  position: fixed;
  min-width: 120px;
  background: #fff;
  border: 1px solid #e4e7ed;
  border-radius: 4px;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
  padding: 5px 0;
  margin: 0;
  list-style: none;
  z-index: 3000;

  .menu-item {
    padding: 8px 16px;
    cursor: pointer;
    font-size: 14px;
    color: #606266;
    transition:
      background-color 0.3s,
      color 0.3s;

    &:hover {
      background-color: #f5f7fa;
      color: var(--el-color-primary);
    }
  }
}
</style>
