<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 v-loading="loading" :data="treeData" :props="treeProps" node-key="id" default-expand-all :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>
            <span 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" v-hasPermi="['document:folder:add']" @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)">
        <li class="menu-item" @click="handleMenuItemClick('add:2', currentMenuData)">
          <span>{{ t('document.document.menu.center') }}</span>
        </li>
        <li class="menu-item" @click="handleMenuItemClick('add:0', currentMenuData)">
          <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)">
          <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>

    <!-- 添加文件夹对话框 -->
    <el-dialog v-model="dialog.visible" :title="dialog.title" width="600px" append-to-body>
      <el-form ref="folderFormRef" :model="form" :rules="rules" label-width="140px">
        <el-form-item :label="t('document.document.form.name')" prop="name">
          <el-input v-model="form.name" :placeholder="t('document.document.form.namePlaceholder')" clearable />
        </el-form-item>
        <el-form-item :label="t('document.document.form.restrictionLevel')" prop="restrictionLevel">
          <el-radio-group v-model="isRestricted" @change="handleRestrictionChange">
            <el-radio :label="false">{{ t('document.document.form.noRestriction') }}</el-radio>
            <el-radio :label="true">{{ t('document.document.form.restricted') }}</el-radio>
          </el-radio-group>
          <el-input-number
            v-if="isRestricted"
            v-model="restrictionLevelValue"
            :min="0"
            :max="10000"
            style="width: 100%; margin-top: 10px"
            :placeholder="t('document.document.form.restrictionLevelPlaceholder')"
          />
        </el-form-item>
        <el-form-item :label="t('document.document.form.note')" prop="note">
          <el-input v-model="form.note" type="textarea" :rows="4" :placeholder="t('document.document.form.notePlaceholder')" />
        </el-form-item>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button :loading="buttonLoading" type="primary" @click="submitFolderForm">{{ t('document.document.button.submit') }}</el-button>
          <el-button @click="cancel">{{ t('document.document.button.cancel') }}</el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, onMounted, onUnmounted, nextTick, getCurrentInstance, watch } from 'vue';
import { useI18n } from 'vue-i18n';
import { listFolder, addFolder, delFolder, getFolder, updateFolder } from '@/api/document/folder';
import { FolderListVO, FolderForm } from '@/api/document/folder/types';
import { Folder, Document, Location, OfficeBuilding, MoreFilled, ArrowRight } from '@element-plus/icons-vue';
import { ElMessage, ElMessageBox } from 'element-plus';
import type { FormInstance } from 'element-plus';
import type { ComponentInternalInstance } from 'vue';

interface Props {
  projectId?: number | string;
}

const props = defineProps<Props>();

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

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

// 数据定义
const loading = ref(false);
const buttonLoading = ref(false);
const treeData = ref<FolderListVO[]>([]);
const folderFormRef = ref<FormInstance>();

// 对话框
const dialog = reactive({
  visible: false,
  title: '',
  isEdit: false
});

// 当前操作的节点
const currentNode = ref<FolderListVO | null>(null);

// 限制层级相关状态
const isRestricted = ref(false);
const restrictionLevelValue = ref(0);

// 表单初始数据
const initFormData: FolderForm = {
  id: undefined,
  projectId: undefined,
  parentId: undefined,
  type: 0,
  name: '',
  status: 0,
  note: '',
  restrictionLevel: -1
};

// 表单数据
const form = ref<FolderForm>({ ...initFormData });

// 表单验证规则
const rules = {
  name: [{ required: true, message: t('document.document.rule.nameRequired'), trigger: 'blur' }],
  type: [{ required: true, message: t('document.document.rule.typeRequired'), trigger: 'change' }]
};

// 树形组件配置
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 res = await listFolder({ projectId: props.projectId } as any);
    treeData.value = res.data || [];
  } catch (error) {
    ElMessage.error(t('document.document.message.getFolderListFailed'));
    console.error(error);
  } finally {
    loading.value = false;
  }
};

// 表单重置
const reset = () => {
  form.value = { ...initFormData };
  isRestricted.value = false;
  restrictionLevelValue.value = 0;
  folderFormRef.value?.resetFields();
};

// 处理限制状态变化
const handleRestrictionChange = (value: boolean) => {
  if (value) {
    form.value.restrictionLevel = restrictionLevelValue.value;
  } else {
    form.value.restrictionLevel = -1;
  }
};

// 监听restrictionLevelValue变化
watch(restrictionLevelValue, (newValue) => {
  if (isRestricted.value) {
    form.value.restrictionLevel = newValue;
  }
});

// 取消按钮
const cancel = () => {
  reset();
  dialog.visible = false;
};

// 新建文件夹（顶级）
const handleAddFolder = () => {
  reset();
  currentNode.value = null;
  form.value.projectId = props.projectId;
  form.value.parentId = undefined;
  dialog.visible = true;
  dialog.title = t('document.document.dialog.addFolder');
  dialog.isEdit = false;
};

// 新增子节点（指定类型）
const handleAddChildWithType = (data: FolderListVO, type: number) => {
  reset();
  currentNode.value = data;
  form.value.projectId = props.projectId;
  form.value.parentId = data.id;
  form.value.type = type;
  dialog.visible = true;
  const typeLabel =
    type === 0 ? t('document.document.type.folder') : type === 1 ? t('document.document.type.country') : t('document.document.type.center');
  dialog.title =
    type === 0
      ? t('document.document.dialog.addFolder')
      : type === 1
        ? t('document.document.dialog.addCountry')
        : t('document.document.dialog.addCenter');
  dialog.isEdit = false;
};

// 提交表单
const submitFolderForm = () => {
  folderFormRef.value?.validate(async (valid: boolean) => {
    if (valid) {
      if (dialog.isEdit) {
        try {
          const confirmMessage = `
            <div style="text-align: left;">
              <p><strong>${t('document.document.confirm.nameLabel')}</strong>${form.value.name}</p>
              <p><strong>${t('document.document.confirm.restrictionLevelLabel')}</strong>${form.value.restrictionLevel}</p>
              <p><strong>${t('document.document.confirm.noteLabel')}</strong>${form.value.note || t('document.document.confirm.noNote')}</p>
            </div>
          `;
          await ElMessageBox.confirm(confirmMessage, t('document.document.dialog.confirmEdit'), {
            confirmButtonText: t('document.document.message.confirmButton'),
            cancelButtonText: t('document.document.message.cancelButton'),
            type: 'warning',
            dangerouslyUseHTMLString: true
          });
        } catch {
          return;
        }
      }

      buttonLoading.value = true;
      try {
        if (dialog.isEdit) {
          await updateFolder(form.value);
          proxy?.$modal.msgSuccess(t('document.document.message.editSuccess'));
        } else {
          await addFolder(form.value);
          proxy?.$modal.msgSuccess(t('document.document.message.addSuccess'));
        }
        dialog.visible = false;
        await getList();
        emit('refresh');
      } catch (error) {
        console.error(dialog.isEdit ? t('document.document.message.editFailed') : t('document.document.message.addFailed'), error);
      } finally {
        buttonLoading.value = false;
      }
    }
  });
};

// 编辑
const handleEdit = async (data: FolderListVO) => {
  reset();
  loading.value = true;
  try {
    const res = await getFolder(data.id);
    Object.assign(form.value, res.data);

    if (form.value.restrictionLevel === -1) {
      isRestricted.value = false;
      restrictionLevelValue.value = 0;
    } else {
      isRestricted.value = true;
      restrictionLevelValue.value = form.value.restrictionLevel;
    }

    currentNode.value = null;
    dialog.visible = true;
    dialog.title = t('document.document.dialog.editFolder');
    dialog.isEdit = true;
  } catch (error) {
    ElMessage.error(t('document.document.message.getFolderInfoFailed'));
    console.error(error);
  } finally {
    loading.value = false;
  }
};

// 删除
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 = (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 {
    primaryMenuStyle.value = {
      left: `${rect.left}px`,
      top: `${rect.bottom + 2}px`
    };

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

// 切换二级菜单显示
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 = (command: string, data: FolderListVO) => {
  if (command.startsWith('add:')) {
    const cmdPart = command.split(':')[1];
    if (cmdPart === 'document') {
      emit('addDocument', data);
    } else {
      const type = parseInt(cmdPart);
      handleAddChildWithType(data, type);
    }
  } else if (command === 'edit') {
    handleEdit(data);
  } else if (command === 'delete') {
    handleDelete(data);
  }
};

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

// 关闭所有菜单
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
});

// 初始化
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: 300px;
  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);
    }
  }

  .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>
