<script setup lang="ts">
/**
 * 用户管理链路管理 - 主页面
 *
 * 功能说明：
 * - 展示用户管理链路的树形结构
 * - 支持节点的展开/折叠
 * - 支持单选/多选节点
 * - 提供新增、编辑、删除（单个/批量）功能
 * - 支持按上级用户 ID 和下级用户 ID 搜索
 *
 * 树形结构特点：
 * - 根节点：最高领导，没有上级
 * - 中间节点：有上级也有下级
 * - 叶子节点：基层员工，没有下级
 */

import { computed, nextTick, onMounted, reactive, ref } from 'vue';
import type { ElTree } from 'element-plus';
import { ElButton, ElPopconfirm, ElTag } from 'element-plus';
import { useBoolean } from '@sa/hooks';
import {
  fetchBatchDeleteUserManagementRelation,
  fetchDeleteUserManagementRelation,
  fetchGetUserListByDeptId,
  fetchGetUserManagementRelation,
  fetchGetUserManagementRelationQuery,
  fetchGetUserManagementRelationTree
} from '@/service/api';
import RelationOperateDialog from './modules/relation-operate-dialog.vue';
import RelationSearch from './modules/relation-search.vue';

defineOptions({ name: 'UserManagementRelation' });

/**
 * 组件 userQuery 定义
 *
 * @param fromUserIndex 是否不是从管理链路 index 页面访问（从 user 页面访问时为 true）
 * @param deptId 部门 ID
 * @param orgType 组织类型（company/dept/function/direction/team）
 */
interface userQuery {
  fromUserIndex?: boolean;
  deptId?: number | null;
  orgType?: string;
}

// 从user的index组件访问管理链路，fromUserIndex为true，否则false; dept=100是灿能电力的id
const { fromUserIndex = false, deptId = 100, orgType = 'company' } = defineProps<userQuery>();

/**
 * 判断节点是否为母节点（根节点）
 *
 * 母节点是指树形数据中的第一层节点
 *
 * @param data 节点数据
 */
/**
 * 判断母节点的编辑按钮是否应该隐藏
 *
 * 当组织类型为部门、方向或团队时，隐藏母节点的编辑按钮
 */
const shouldHideRootEdit = computed(() => {
  return fromUserIndex && orgType;
});

/**
 * 初始化搜索参数
 *
 * @returns 搜索参数对象
 */
function getInitSearchParams(): Api.SystemManage.UserManagementRelationQueryReqVO {
  return {
    managerUserId: undefined,
    subordinateUserId: undefined
  };
}

// 搜索参数
const searchParams = reactive(getInitSearchParams());

// 用户列表（供搜索组件和对话框组件共享）
const userList = ref<Api.SystemManage.UserSimple[]>([]);

// 树形组件引用
const relationTreeRef = ref<InstanceType<typeof ElTree>>();

// 已选中的节点 ID 列表
const checkedNodeKeys = ref<string[]>([]);

// 树形数据
const treeData = ref<Api.SystemManage.UserManagementRelationTreeRespVO[]>([]);

function isRootNode(data: Api.SystemManage.UserManagementRelationTreeRespVO): boolean {
  return treeData.value.some(node => node.userId === data.userId);
}

// 加载状态
const loading = ref(false);

// 树形配置
const treeProps: any = {
  children: 'children',
  label: 'userNickname',
  isLeaf: (data: Api.SystemManage.UserManagementRelationTreeRespVO) => !data.children || data.children.length === 0
};

/**
 * 加载用户列表
 *
 * 获取用户简单列表，供搜索组件和对话框组件共享使用
 */
async function loadUserList() {
  const { data, error } = await fetchGetUserListByDeptId(deptId);
  if (!error) {
    userList.value = data || [];
  }
}

/**
 * 加载树形数据
 *
 * 调用后端接口获取完整的用户管理链路树
 */
async function loadTreeData() {
  loading.value = true;

  try {
    // 默认不是来自user的index组件访问且deptId=100，查询灿能电力及其以下所有部门的用户的管理链路
    const query: Api.SystemManage.UserManagementRelationQueryReqVO = {
      fromUserIndex,
      deptId
    };
    const { data, error } = await fetchGetUserManagementRelationTree(query);

    if (!error) {
      treeData.value = data || [];
    }
  } finally {
    loading.value = false;
  }
}

/**
 * 根据搜索条件查询树形数据
 *
 * 调用后端接口获取符合条件的用户管理链路树
 *
 * @param query 查询参数
 */
async function loadTreeDataByQuery(query: Api.SystemManage.UserManagementRelationQueryReqVO) {
  loading.value = true;

  try {
    const { data, error } = await fetchGetUserManagementRelationQuery(query);

    if (!error) {
      treeData.value = data || [];
    }
  } finally {
    loading.value = false;
  }
}

/**
 * 刷新树形数据
 *
 * 从后端重新加载整个树数据
 */
async function reloadTreeData() {
  // 保存当前展开状态
  saveExpandedState();

  checkedNodeKeys.value = [];
  await loadTreeData();

  // 等待 Vue 渲染树节点
  await nextTick();
  await nextTick();
  await nextTick();

  // 数据更新后恢复展开状态
  await restoreExpandedState();

  await nextTick();
  relationTreeRef.value?.setCheckedKeys([]);
}

/**
 * 在本地树数据中插入新节点
 *
 * 当从树节点新增时，直接在对应父节点下插入新节点，避免整棵树重新加载
 *
 * @param managerUserId 上级用户 ID（父节点）
 * @param newRelationId 新增的关系 ID
 */
async function insertNodeLocally(managerUserId: string, newRelationId: string) {
  // 从后端获取新增节点的详情
  const { data: relationDetail, error } = await fetchGetUserManagementRelation(newRelationId);

  if (error || !relationDetail) {
    // 如果获取详情失败，降级为重新加载整棵树
    await reloadTreeData();
    return;
  }

  // 构建树节点数据
  const newNode: Api.SystemManage.UserManagementRelationTreeRespVO = {
    id: relationDetail.id,
    userId: relationDetail.subordinateUserId || '',
    userNickname: '',
    managerUserId: relationDetail.managerUserId || '',
    managerNickname: '',
    children: []
  };

  // 在用户列表中查找下级用户的昵称
  const subordinateUser = userList.value.find(u => u.id === relationDetail.subordinateUserId);
  if (subordinateUser) {
    newNode.userNickname = subordinateUser.nickname;
  }

  // 在用户列表中查找上级用户的昵称
  const managerUser = userList.value.find(u => u.id === relationDetail.managerUserId);
  if (managerUser) {
    newNode.managerNickname = managerUser.nickname;
  }

  // 递归查找并插入节点
  function insertIntoTree(nodes: Api.SystemManage.UserManagementRelationTreeRespVO[]): boolean {
    for (const node of nodes) {
      if (node.userId === managerUserId) {
        // 找到父节点，插入新节点
        if (!node.children) {
          node.children = [];
        }
        node.children.push(newNode);
        return true;
      }

      // 递归查找子节点
      if (node.children && node.children.length > 0) {
        if (insertIntoTree(node.children)) {
          return true;
        }
      }
    }
    return false;
  }

  const inserted = insertIntoTree(treeData.value);

  if (!inserted) {
    // 如果没有找到父节点，说明新增的是根节点，重新加载整棵树
    await reloadTreeData();
    return;
  }

  // 展开父节点
  await nextTick();
  const tree = relationTreeRef.value;
  if (tree) {
    const treeNode = tree.getNode(managerUserId);
    if (treeNode && !treeNode.expanded) {
      treeNode.expand();
    }
  }
}

/**
 * 从本地树数据中删除节点
 *
 * 当删除节点时，直接从本地数据中移除，避免整棵树重新加载
 *
 * @param nodeToDelete 要删除的节点
 */
function removeNodeLocally(nodeToDelete: Api.SystemManage.UserManagementRelationTreeRespVO) {
  // 递归查找并删除节点
  function removeFromTree(nodes: Api.SystemManage.UserManagementRelationTreeRespVO[]): boolean {
    const index = nodes.findIndex(n => n.userId === nodeToDelete.userId);

    if (index !== -1) {
      nodes.splice(index, 1);
      return true;
    }

    // 递归查找子节点
    for (const node of nodes) {
      if (node.children && node.children.length > 0) {
        if (removeFromTree(node.children)) {
          return true;
        }
      }
    }

    return false;
  }

  removeFromTree(treeData.value);
}

/**
 * 展开树的所有节点
 */
async function expandAllNodes() {
  await nextTick();
  await nextTick();

  const tree = relationTreeRef.value;
  if (!tree || !treeData.value.length) {
    return;
  }

  // 递归展开所有节点
  function expandNodes(nodes: Api.SystemManage.UserManagementRelationTreeRespVO[]) {
    for (const node of nodes) {
      const treeNode = tree?.getNode(node.userId);
      if (treeNode && !treeNode.expanded) {
        treeNode.expand();
      }

      if (node.children && node.children.length > 0) {
        expandNodes(node.children);
      }
    }
  }

  expandNodes(treeData.value);
}

/**
 * 处理搜索
 *
 * 根据搜索条件查询树形数据
 * 如果有搜索条件，调用 query 接口；否则调用 tree 接口
 */
async function handleSearch() {
  checkedNodeKeys.value = [];

  // 判断是否有搜索条件
  const hasSearchCondition = searchParams.subordinateUserId !== undefined && searchParams.subordinateUserId !== null;
  if (hasSearchCondition) {
    // 有搜索条件，调用查询接口
    const query: Api.SystemManage.UserManagementRelationQueryReqVO = {
      subordinateUserId: searchParams.subordinateUserId,
      fromUserIndex,
      deptId
    };
    await loadTreeDataByQuery(query);
  } else {
    // 无搜索条件，加载完整树
    await loadTreeData();
  }

  // 搜索后展开所有节点
  await expandAllNodes();

  await nextTick();
  relationTreeRef.value?.setCheckedKeys([]);
}

/**
 * 保存当前展开的节点 ID 列表
 * 用于在刷新数据后恢复展开状态
 */
const expandedNodeKeys = ref<string[]>([]);

/**
 * 重置搜索
 *
 * 清空搜索条件并重新加载数据
 */
async function resetSearchParams() {
  Object.assign(searchParams, getInitSearchParams());

  // 清空保存的展开状态，让 reloadTreeData 后展开前两层
  expandedNodeKeys.value = [];

  await reloadTreeData();
}

// 对话框相关状态
const { bool: operateVisible, setTrue: openOperateModal, setFalse: closeOperateModal } = useBoolean();
const operateType = ref<UI.TableOperateType>('add');
const editingData = ref<Api.SystemManage.UserManagementRelation | null>(null);

/**
 * 是否在管理链路树中选中节点后点击新增
 * 用于控制新增对话框中上级用户下拉框是否禁用
 */
const isAddFromTreeNode = ref(false);

/**
 * 打开新增对话框
 *
 * @param item 当前节点数据，用于设置默认上级为此节点用户
 */
function openAdd(item?: Api.SystemManage.UserManagementRelationTreeRespVO) {
  operateType.value = 'add';

  // 如果是从树节点点击的新增按钮，标记为来自树节点
  isAddFromTreeNode.value = Boolean(item);

  // 如果是从某一行的新增按钮触发，则默认上级为当前节点用户
  // 否则默认上级为当前登录用户（在对话框组件中处理）
  editingData.value = item
    ? {
        id: null,
        managerUserId: item.userId,
        subordinateUserId: null,
        effectiveFrom: null,
        effectiveUntil: null,
        remark: null,
        createTime: Date.now()
      }
    : null;
  openOperateModal();
}

/**
 * 打开编辑对话框
 *
 * @param item 要编辑的关系记录
 */
function openEdit(item: Api.SystemManage.UserManagementRelationTreeRespVO) {
  operateType.value = 'edit';
  // 构建树节点数据为编辑所需格式
  editingData.value = item.id
    ? {
        id: item.id,
        managerUserId: item.managerUserId,
        subordinateUserId: item.userId,
        effectiveFrom: null,
        effectiveUntil: null,
        remark: null,
        createTime: Date.now()
      }
    : null;
  openOperateModal();
}

/**
 * 删除单个节点的关系记录
 *
 * @param item 要删除的关系记录
 */
async function handleDelete(item: Api.SystemManage.UserManagementRelationTreeRespVO) {
  const { error } = await fetchDeleteUserManagementRelation(item.id);

  if (error) {
    return;
  }

  window.$message?.success('删除成功');

  // 使用局部删除，保持树的展开状态
  removeNodeLocally(item);
}

/**
 * 批量删除关系记录
 *
 * 删除所有选中的节点
 */
async function handleBatchDelete() {
  if (!checkedNodeKeys.value.length) {
    return;
  }

  // 保存要删除的节点数据（用于局部删除）
  const nodesToDelete: Api.SystemManage.UserManagementRelationTreeRespVO[] = [];

  // 递归查找选中的节点
  function collectCheckedNodes(nodes: Api.SystemManage.UserManagementRelationTreeRespVO[], keys: string[]) {
    for (const node of nodes) {
      if (keys.includes(node.userId)) {
        nodesToDelete.push(node);
      }
      if (node.children && node.children.length > 0) {
        collectCheckedNodes(node.children, keys);
      }
    }
  }

  collectCheckedNodes(treeData.value, checkedNodeKeys.value);

  const { error } = await fetchBatchDeleteUserManagementRelation(checkedNodeKeys.value);

  if (error) {
    return;
  }

  window.$message?.success('删除成功');

  // 使用局部删除，保持树的展开状态
  for (const node of nodesToDelete) {
    removeNodeLocally(node);
  }
}

/**
 * 处理树节点勾选变化
 *
 * @param checkedData 当前选中的节点数据
 * @param checkedInfo 包含 checkedKeys 和 halfCheckedKeys 的对象
 */
function handleNodeCheck(checkedData: any, checkedInfo: any) {
  checkedNodeKeys.value = checkedInfo.checkedNodes
    .map((node: any) => node.id)
    .filter((id: string | null): id is string => Boolean(id));
}

/**
 * 保存当前展开的节点状态
 */
function saveExpandedState() {
  if (!relationTreeRef.value) {
    return;
  }

  const store = (relationTreeRef.value as any).store;
  if (!store) {
    return;
  }

  const allNodes = store.nodesMap || {};
  expandedNodeKeys.value = [];

  Object.keys(allNodes).forEach(key => {
    const node = allNodes[key];
    if (node && node.expanded && node.data && node.data.userId) {
      expandedNodeKeys.value.push(node.data.userId);
    }
  });
}

/**
 * 处理对话框提交事件
 *
 * @param relationId 提交后的关系 ID
 */
async function handleSubmitted(relationId: string) {
  closeOperateModal();

  // 如果是从树节点新增，使用局部插入
  if (operateType.value === 'add' && isAddFromTreeNode.value && editingData.value?.managerUserId) {
    await insertNodeLocally(editingData.value.managerUserId, relationId);
  } else {
    // 其他情况（头部新增、编辑）重新加载整棵树
    await reloadTreeData();
  }

  // 重置标记
  isAddFromTreeNode.value = false;
}

/**
 * 展开树的前两层节点
 *
 * 只展开根节点和它们的直接子节点，第三层及更深层保持折叠
 */
function expandFirstTwoLevels() {
  const tree = relationTreeRef.value;
  if (!tree || !treeData.value.length) {
    return;
  }

  // 展开第一层（根节点）
  for (const rootNode of treeData.value) {
    const treeNode = tree.getNode(rootNode.userId);
    if (treeNode) {
      treeNode.expand();
    }

    // 展开第二层（根节点的直接子节点）
    if (rootNode.children && rootNode.children.length > 0) {
      for (const childNode of rootNode.children) {
        const childTreeNode = tree.getNode(childNode.userId);
        if (childTreeNode) {
          childTreeNode.expand();
        }
      }
    }
  }
}

/**
 * 恢复树节点的展开状态
 *
 * 根据之前保存的展开状态，恢复对应的节点展开
 */
async function restoreExpandedState() {
  await nextTick();
  await nextTick();

  const tree = relationTreeRef.value;
  if (!tree) {
    return;
  }

  if (expandedNodeKeys.value.length > 0) {
    // 恢复之前展开的节点
    for (const key of expandedNodeKeys.value) {
      const node = tree.getNode(key);
      if (node && !node.expanded) {
        node.expand();
      }
    }
  } else {
    // 如果是首次加载或没有保存的状态，展开前两层
    expandFirstTwoLevels();
  }
}

/**
 * 判断节点是否有子节点
 *
 * 有子节点的节点不允许删除
 *
 * @param node 树节点
 */
function hasChildren(node: Api.SystemManage.UserManagementRelationTreeRespVO): boolean {
  return Boolean(node.children && node.children.length > 0);
}

/**
 * 计算树形数据中所有节点的数量
 *
 * 递归遍历树形结构，统计所有节点总数
 *
 * @param nodes 树形数据数组
 * @returns 节点总数
 */
function countTreeNodes(nodes: Api.SystemManage.UserManagementRelationTreeRespVO[]): number {
  let count = 0;
  for (const node of nodes) {
    count += 1;
    if (node.children && node.children.length > 0) {
      count += countTreeNodes(node.children);
    }
  }
  return count;
}

onMounted(async () => {
  await loadUserList();
  await reloadTreeData();
});
</script>

<template>
  <div class="flex-col-stretch gap-16px overflow-hidden" style="height: calc(70vh - 120px)">
    <!-- 搜索区域 -->
    <RelationSearch
      v-model:model="searchParams"
      :user-list="userList"
      @reset="resetSearchParams"
      @search="handleSearch"
    />

    <!-- 树形卡片区域 -->
    <ElCard class="min-h-0 flex-1-hidden card-wrapper">
      <template #header>
        <div class="flex items-center justify-between gap-12px">
          <div class="flex items-center gap-10px">
            <p>用户管理链路树</p>
            <ElTag effect="plain">{{ countTreeNodes(treeData) }}</ElTag>
          </div>
          <div class="flex items-center gap-10px">
            <ElButton plain type="primary" @click="openAdd()">
              <template #icon>
                <icon-ic-round-plus class="text-icon" />
              </template>
              新增
            </ElButton>
            <!--            <ElPopconfirm title="确认删除选中的关系吗？" @confirm="handleBatchDelete">-->
            <!--              <template #reference>-->
            <!--                <ElButton type="danger" plain :disabled="checkedNodeKeys.length === 0">-->
            <!--                  <template #icon>-->
            <!--                    <icon-ic-round-delete class="text-icon"/>-->
            <!--                  </template>-->
            <!--                  批量删除-->
            <!--                </ElButton>-->
            <!--              </template>-->
            <!--            </ElPopconfirm>-->
            <ElButton @click="reloadTreeData">
              <template #icon>
                <icon-ic-round-refresh class="text-icon" />
              </template>
              刷新
            </ElButton>
          </div>
        </div>
      </template>

      <!-- 树形组件 -->
      <div class="flex-1 overflow-auto">
        <ElTree
          ref="relationTreeRef"
          v-loading="loading"
          :data="treeData"
          :props="treeProps"
          node-key="userId"
          :expand-on-click-node="false"
          @check="handleNodeCheck"
        >
          <template #default="{ node, data }">
            <div class="flex flex-1 items-center justify-between">
              <span class="flex items-center gap-8px">
                <span>{{ node.label }}</span>
                <!--                <ElTag v-if="data.managerNickname" size="small" type="info">上级：{{ data.managerNickname }}</ElTag>-->
              </span>
              <div class="flex items-center" style="min-width: 200px">
                <ElButton link type="primary" size="default" @click.stop="openAdd(data)">
                  <template #icon>
                    <icon-ic-round-plus class="text-icon" />
                  </template>
                  新增
                </ElButton>
                <ElButton
                  v-if="!(isRootNode(data) && shouldHideRootEdit)"
                  link
                  type="primary"
                  size="small"
                  @click.stop="openEdit(data)"
                >
                  <template #icon>
                    <icon-ic-round-edit class="text-icon" />
                  </template>
                  编辑
                </ElButton>
                <ElPopconfirm
                  v-if="!hasChildren(data) && data.id"
                  title="确认删除当前关系吗？"
                  @confirm="handleDelete(data)"
                >
                  <template #reference>
                    <ElButton link type="danger" size="small">
                      <template #icon>
                        <icon-ic-round-delete class="text-icon" />
                      </template>
                      删除
                    </ElButton>
                  </template>
                </ElPopconfirm>
              </div>
            </div>
          </template>
        </ElTree>
      </div>
    </ElCard>

    <!-- 操作对话框 -->
    <RelationOperateDialog
      v-model:visible="operateVisible"
      :operate-type="operateType"
      :row-data="editingData"
      :user-list="userList"
      :is-add-from-tree-node="isAddFromTreeNode"
      @submitted="handleSubmitted"
    />
  </div>
</template>

<style lang="scss" scoped>
:deep(.el-card__body) {
  height: calc(100% - 56px);
  display: flex;
  flex-direction: column;
}

:deep(.el-tree-node__content) {
  height: auto;
  padding: 10px 0;
  border-bottom: 1px solid var(--el-border-color-lighter);

  &:hover {
    background-color: var(--el-fill-color-light);
  }
}

:deep(.el-tree-node__label) {
  flex: 1;
  display: flex;
  align-items: center;
}
</style>
