<template>
  <div class="permissions-container">
    <el-card>
      <template #header>
        <div class="card-header">
          <span class="title">
            <el-icon><Key /></el-icon>
            权限管理
          </span>
          <span class="subtitle">为角色分配菜单和API访问权限</span>
        </div>
      </template>

      <el-row :gutter="20">
        <!-- 左侧：角色列表 -->
        <el-col :span="8">
          <el-card shadow="hover" class="role-card">
            <template #header>
              <div class="card-title">
                <el-icon><UserFilled /></el-icon>
                <span>角色列表</span>
              </div>
            </template>
            
            <el-input
              v-model="roleSearchQuery"
              placeholder="搜索角色..."
              :prefix-icon="Search"
              clearable
              class="search-input"
            />

            <el-scrollbar height="600px" class="role-list">
              <div
                v-for="role in filteredRoles"
                :key="role.roleId"
                :class="['role-item', { active: selectedRole?.roleId === role.roleId }]"
                @click="selectRole(role)"
              >
                <div class="role-info">
                  <div class="role-name">{{ role.roleName }}</div>
                  <div class="role-code">{{ role.roleCode }}</div>
                </div>
                <el-icon v-if="selectedRole?.roleId === role.roleId" class="check-icon">
                  <Check />
                </el-icon>
              </div>
              
              <el-empty v-if="filteredRoles.length === 0" description="暂无角色数据" />
            </el-scrollbar>
          </el-card>
        </el-col>

        <!-- 右侧：权限分配 -->
        <el-col :span="16">
          <el-card shadow="hover" class="permission-card">
            <template #header>
              <div class="card-title">
                <el-icon><Menu /></el-icon>
                <span>权限分配</span>
                <span v-if="selectedRole" class="selected-role-name">
                  （{{ selectedRole.roleName }}）
                </span>
              </div>
            </template>

            <div v-if="!selectedRole" class="empty-state">
              <el-empty description="请先选择一个角色" />
            </div>

            <div v-else class="permission-content">
              <!-- 搜索和操作按钮 -->
              <div class="toolbar">
                <el-input
                  v-model="permissionSearchQuery"
                  placeholder="搜索菜单..."
                  :prefix-icon="Search"
                  clearable
                  style="width: 300px;"
                />
                
                <div class="actions">
                  <el-button @click="expandAll">全部展开</el-button>
                  <el-button @click="collapseAll">全部折叠</el-button>
                  <el-button @click="checkAll">全选</el-button>
                  <el-button @click="uncheckAll">取消全选</el-button>
                </div>
              </div>

              <!-- 权限树 -->
              <el-scrollbar height="550px" class="tree-container">
                <el-tree
                  ref="permissionTree"
                  :data="menuTreeData"
                  :props="treeProps"
                  :filter-node-method="filterNode"
                  node-key="menu_id"
                  show-checkbox
                  :default-expand-all="false"
                  :check-strictly="false"
                  class="permission-tree"
                >
                  <template #default="{ node, data }">
                    <div class="custom-tree-node">
                      <div class="node-content">
                        <el-icon v-if="data.menu_type === 1" class="menu-icon">
                          <Folder />
                        </el-icon>
                        <el-icon v-else-if="data.menu_type === 2" class="page-icon">
                          <Document />
                        </el-icon>
                        <el-icon v-else class="api-icon">
                          <Link />
                        </el-icon>
                        <span class="node-label">{{ node.label }}</span>
                      </div>
                      <div class="node-info">
                        <el-tag v-if="data.menu_type === 1" type="primary" size="small">
                          目录
                        </el-tag>
                        <el-tag v-else-if="data.menu_type === 2" type="success" size="small">
                          页面
                        </el-tag>
                        <el-tag v-else type="warning" size="small">
                          按钮
                        </el-tag>
                        <el-tag v-if="data.permission" type="info" size="small" class="permission-tag">
                          {{ data.permission }}
                        </el-tag>
                      </div>
                    </div>
                  </template>
                </el-tree>
              </el-scrollbar>

              <!-- 保存按钮 -->
              <div class="footer">
                <el-button type="primary" @click="savePermissions" :loading="saving">
                  <el-icon><Select /></el-icon>
                  保存权限设置
                </el-button>
                <el-button @click="resetPermissions">
                  <el-icon><RefreshLeft /></el-icon>
                  重置
                </el-button>
              </div>
            </div>
          </el-card>
        </el-col>
      </el-row>
    </el-card>
  </div>
</template>

<script setup>
import { ref, computed, watch, nextTick } from 'vue';
import { ElMessage, ElMessageBox } from 'element-plus';
import {
  Key,
  UserFilled,
  Menu,
  Search,
  Check,
  Folder,
  Link,
  Document,
  Select,
  RefreshLeft,
} from '@element-plus/icons-vue';
import { getRoleByTenantId, getAllRoles } from '@/api/role';
import {
  getAllMenuPermissions,
  getRolePermissions,
  assignRolePermissions,
} from '@/api/permission.js';
import { useAuthStore } from '@/stores/auth';

// 角色相关
const roleList = ref([]);
const roleSearchQuery = ref('');
const selectedRole = ref(null);
const authStore = useAuthStore();

// 权限相关
const allMenus = ref([]);
const menuTreeData = ref([]);
const permissionSearchQuery = ref('');
const permissionTree = ref(null);
const saving = ref(false);

// 树配置
const treeProps = {
  children: 'children',
  label: 'menu_name',
};

// 过滤后的角色列表
const filteredRoles = computed(() => {
  if (!roleSearchQuery.value) {
    return roleList.value;
  }
  const query = roleSearchQuery.value.toLowerCase();
  return roleList.value.filter(
    (role) =>
      role.roleName.toLowerCase().includes(query) ||
      role.roleCode.toLowerCase().includes(query)
  );
});

// 加载所有菜单权限（根据选中的角色过滤）
const loadAllMenus = async (roleId = null) => {
  try {
    // 如果提供了roleId，传递给接口用于根据角色的default值过滤菜单
    const params = roleId ? { roleId } : {};
    const res = await getAllMenuPermissions(params);
    
    if (res.success && res.data) {
      allMenus.value = res.data;
      buildMenuTree();
    }
  } catch (error) {
    console.error('加载菜单列表失败:', error);
    ElMessage.error('加载菜单列表失败');
  }
};

// 构建菜单树
const buildMenuTree = () => {
  const tree = [];
  const map = new Map();

  // 先创建所有节点的映射
  allMenus.value.forEach((menu) => {
    map.set(menu.menu_id, { ...menu, children: [] });
  });

  // 构建树形结构
  allMenus.value.forEach((menu) => {
    const node = map.get(menu.menu_id);
    if (menu.parent_id === 0) {
      tree.push(node);
    } else {
      const parent = map.get(menu.parent_id);
      if (parent) {
        parent.children.push(node);
      }
    }
  });

  menuTreeData.value = tree;
};

// 选择角色
const selectRole = async (role) => {
  selectedRole.value = role;
  // 重新加载菜单列表（根据角色的default值过滤）
  await loadAllMenus(role.roleId);
  await loadRolePermissions(role.roleId);
};

// 加载角色权限
const loadRolePermissions = async (roleId) => {
  try {
    const res = await getRolePermissions(roleId);
    
    if (res.success && res.data) {
      // 等待树渲染完成
      await nextTick();
      
      // 设置选中的节点
      if (permissionTree.value) {
        permissionTree.value.setCheckedKeys(res.data.menu_ids || []);
      }
    }
  } catch (error) {
    console.error('加载角色权限失败:', error);
    ElMessage.error('加载角色权限失败');
  }
};

// 保存权限
const savePermissions = async () => {
  if (!selectedRole.value) {
    ElMessage.warning('请先选择角色');
    return;
  }

  try {
    // 只获取完全选中的节点（不包括半选中的父节点）
    // 因为半选中的父节点表示部分子节点被选中，父节点本身不需要权限记录
    const checkedKeys = permissionTree.value.getCheckedKeys();
    const menuIds = checkedKeys;

    saving.value = true;
    const res = await assignRolePermissions(selectedRole.value.roleId, menuIds);

    if (res.success) {
      ElMessage.success('权限保存成功');
      await loadRolePermissions(selectedRole.value.roleId);
    } else {
      ElMessage.error(res.message || '权限保存失败');
    }
  } catch (error) {
    console.error('保存权限失败:', error);
    if (error.code === 'ECONNABORTED' || error.message?.includes('timeout')) {
      ElMessage.error('请求超时，请重试。如果数据量较大，可能需要更长时间');
    } else {
      ElMessage.error(error.message || '保存权限失败，请稍后重试');
    }
  } finally {
    saving.value = false;
  }
};

// 重置权限
const resetPermissions = async () => {
  if (!selectedRole.value) {
    return;
  }

  try {
    await ElMessageBox.confirm('确定要重置权限设置吗？', '提示', {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning',
    });

    await loadRolePermissions(selectedRole.value.roleId);
    ElMessage.success('已重置');
  } catch (error) {
    // 用户取消操作
  }
};

// 全部展开
const expandAll = () => {
  if (permissionTree.value) {
    const allKeys = allMenus.value.map((m) => m.menu_id);
    allKeys.forEach((key) => {
      const node = permissionTree.value.getNode(key);
      if (node) {
        node.expanded = true;
      }
    });
  }
};

// 全部折叠
const collapseAll = () => {
  if (permissionTree.value) {
    const allKeys = allMenus.value.map((m) => m.menu_id);
    allKeys.forEach((key) => {
      const node = permissionTree.value.getNode(key);
      if (node) {
        node.expanded = false;
      }
    });
  }
};

// 全选
const checkAll = () => {
  if (permissionTree.value) {
    const allKeys = allMenus.value.map((m) => m.menu_id);
    permissionTree.value.setCheckedKeys(allKeys);
  }
};

// 取消全选
const uncheckAll = () => {
  if (permissionTree.value) {
    permissionTree.value.setCheckedKeys([]);
  }
};

// 过滤节点
const filterNode = (value, data) => {
  if (!value) return true;
  return (
    data.menu_name.toLowerCase().includes(value.toLowerCase()) ||
    (data.path && data.path.toLowerCase().includes(value.toLowerCase())) ||
    (data.permission && data.permission.toLowerCase().includes(value.toLowerCase()))
  );
};

// 监听搜索框变化
watch(permissionSearchQuery, (val) => {
  if (permissionTree.value) {
    permissionTree.value.filter(val);
  }
});

// 初始化
const init = async () => {
  await loadRoles();
  await loadAllMenus();
};

init();
</script>

<style lang="less" scoped>
.permissions-container {

  .card-header {
    display: flex;
    align-items: center;
    justify-content: space-between;

    .title {
      display: flex;
      align-items: center;
      gap: 8px;
      font-size: 18px;
      font-weight: 600;
      color: #303133;
    }

    .subtitle {
      font-size: 13px;
      color: #909399;
    }
  }

  .role-card,
  .permission-card {
    height: 100%;

    .card-title {
      display: flex;
      align-items: center;
      gap: 8px;
      font-size: 16px;
      font-weight: 600;

      .selected-role-name {
        font-size: 14px;
        color: var(--el-color-primary);
        font-weight: normal;
      }
    }
  }

  .search-input {
    margin-bottom: 16px;
  }

  .role-list {
    margin-top: 16px;

    .role-item {
      display: flex;
      align-items: center;
      justify-content: space-between;
      padding: 12px 16px;
      margin-bottom: 8px;
      background: #f5f7fa;
      border-radius: 8px;
      cursor: pointer;
      transition: all 0.3s;

      &:hover {
        background: #e6f0ff;
        transform: translateX(4px);
      }

      &.active {
        background: var(--el-color-primary-light-9);
        border-left: 3px solid var(--el-color-primary);

        .role-name {
          color: var(--el-color-primary);
          font-weight: 600;
        }
      }

      .role-info {
        flex: 1;

        .role-name {
          font-size: 15px;
          font-weight: 500;
          color: #303133;
          margin-bottom: 4px;
        }

        .role-code {
          font-size: 12px;
          color: #909399;
        }
      }

      .check-icon {
        color: var(--el-color-primary);
        font-size: 20px;
      }
    }
  }

  .permission-content {
    .toolbar {
      display: flex;
      justify-content: space-between;
      align-items: center;
      margin-bottom: 16px;
      padding-bottom: 16px;
      border-bottom: 1px solid #ebeef5;

      .actions {
        display: flex;
        gap: 8px;
      }
    }

    .tree-container {
      margin-bottom: 16px;
      padding: 16px;
      background: #fafafa;
      border-radius: 8px;
    }

    .permission-tree {
      background: transparent;

      :deep(.el-tree-node__content) {
        height: auto;
        padding: 8px 0;
        margin-bottom: 4px;

        &:hover {
          background: #e6f0ff;
        }
      }

      .custom-tree-node {
        flex: 1;
        display: flex;
        align-items: center;
        justify-content: space-between;
        padding-right: 16px;

        .node-content {
          display: flex;
          align-items: center;
          gap: 8px;

          .menu-icon {
            color: var(--el-color-primary);
          }

          .api-icon {
            color: var(--el-color-success);
          }

          .node-label {
            font-size: 14px;
            color: #303133;
          }
        }

        .node-info {
          display: flex;
          align-items: center;
          gap: 8px;

          .permission-tag {
            font-family: 'Courier New', monospace;
          }
        }
      }
    }

    .footer {
      display: flex;
      justify-content: center;
      gap: 16px;
      padding-top: 16px;
      border-top: 1px solid #ebeef5;
    }
  }

  .empty-state {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 400px;
  }
}
</style>
