import { useState, useEffect, useRef } from "react";
import { ClientLoaderFunctionArgs, ClientActionFunctionArgs } from "@remix-run/react";
import { Card } from "~/components/ui/Card";
import { Button } from "~/components/ui/Button";
import { Modal } from "~/components/ui/Modal";
import { toastService } from "~/components/ui/Toast";
import {
  getRoles,
  getRoutes,
  getRoleRoutePermissions,
  updateRoleRoutePermissions,
  getRoleRoutesWithPermissions,
  saveRoleApiPermissions,
  getRolePermissions,
  getRoleUsers,
  getAllUsers,
  assignUserRoles,
  createRole,
  updateRole,
  deleteRole,
  revokeUserRole,
  getUserRoles,
  getRoutePermissions,
  isSharedPermission,
  type RoleInfo,
  type RouteInfo,
  type UserInfo,
  type ApiPermission
} from "~/api/role-permissions/role-permissions";
import rolePermissionsStyles from "~/styles/pages/role-permissions.css?url";

// 引入样式
export function links() {
  return [
    { rel: "stylesheet", href: rolePermissionsStyles }
  ];
}

// 页面元数据
export const meta = () => {
  return [
    { title: "角色权限管理 - 中国烟草AI合同及卷宗审核系统" },
    { name: "description", content: "管理系统角色和权限分配" }
  ];
};

// ==================== 辅助函数 ====================

/**
 * 数据范围转中文
 */
function getDataScopeLabel(scope: string): string {
  const map: Record<string, string> = {
    'ALL': '全部数据',
    'DEPT': '地市级数据',
    'SELF': '仅本人数据'
  };
  return map[scope] || scope;
}

// ClientLoader - 加载初始数据
export async function clientLoader({ request }: ClientLoaderFunctionArgs) {
  // ==================== 权限校验 ====================
  // 不在这里做权限检查，因为路由权限已经在 root.tsx 中检查过了
  // 如果用户能访问到这个页面，说明已经通过了路由权限检查
  //
  // 原有的客户端权限检查逻辑已移除，统一使用 root.tsx 的路由权限控制
  // 这样可以避免：
  // 1. 路由权限通过但页面权限不通过的冲突
  // 2. localStorage.user_info 数据不完整导致的误判
  // 3. 重复的权限检查逻辑

  // ==================== 加载数据 ====================
  try {
    const [roles, routes, users] = await Promise.all([
      getRoles(),
      getRoutes(),
      getAllUsers()
    ]);

    return {
      roles,
      routes,
      users
    };
  } catch (error) {
    console.error("加载数据失败:", error);
    return {
      roles: [],
      routes: [],
      users: []
    };
  }
}

// ClientAction - 处理用户操作
export async function clientAction({ request }: ClientActionFunctionArgs) {
  const formData = await request.formData();
  const action = formData.get("action") as string;

  try {
    switch (action) {
      case "updatePermissions": {
        const roleId = parseInt(formData.get("roleId") as string);
        const routeIds = JSON.parse(formData.get("routeIds") as string);
        const result = await updateRoleRoutePermissions(roleId, routeIds);
        return result;
      }

      case "assignUserRoles": {
        const userId = parseInt(formData.get("userId") as string);
        const roleIds = JSON.parse(formData.get("roleIds") as string);
        const result = await assignUserRoles(userId, roleIds);
        return result;
      }

      case "createRole": {
        const roleData = JSON.parse(formData.get("roleData") as string);
        const result = await createRole(roleData);
        return result;
      }

      case "updateRole": {
        const roleId = parseInt(formData.get("roleId") as string);
        const roleData = JSON.parse(formData.get("roleData") as string);
        const result = await updateRole(roleId, roleData);
        return result;
      }

      case "deleteRole": {
        const roleId = parseInt(formData.get("roleId") as string);
        const result = await deleteRole(roleId);
        return result;
      }

      default:
        return { success: false, message: "未知操作" };
    }
  } catch (error) {
    console.error("操作失败:", error);
    return {
      success: false,
      message: error instanceof Error ? error.message : "操作失败"
    };
  }
}

// ==================== 创建角色模态框 ====================

interface CreateRoleModalProps {
  isOpen: boolean;
  onClose: () => void;
  onSuccess: () => void;
}

function CreateRoleModal({ isOpen, onClose, onSuccess }: CreateRoleModalProps) {
  const [formData, setFormData] = useState({
    role_key: '',
    role_name: '',
    description: '',
    data_scope: 'SELF' as 'ALL' | 'DEPT' | 'SELF',
    priority: 10
  });

  const [loading, setLoading] = useState(false);
  const [errors, setErrors] = useState<Record<string, string>>({});

  // 重置表单
  const resetForm = () => {
    setFormData({
      role_key: '',
      role_name: '',
      description: '',
      data_scope: 'SELF',
      priority: 10
    });
    setErrors({});
  };

  // 验证表单
  const validateForm = (): boolean => {
    const newErrors: Record<string, string> = {};

    if (!formData.role_key.trim()) {
      newErrors.role_key = '角色标识不能为空';
    } else if (!/^[a-z][a-z0-9_]*$/.test(formData.role_key)) {
      newErrors.role_key = '角色标识只能包含小写字母、数字、下划线，且必须以字母开头';
    }

    if (!formData.role_name.trim()) {
      newErrors.role_name = '角色名称不能为空';
    }

    setErrors(newErrors);
    return Object.keys(newErrors).length === 0;
  };

  // 提交表单
  const handleSubmit = async (e?: React.FormEvent) => {
    if (e) e.preventDefault();

    if (!validateForm()) {
      toastService.error('请填写正确的表单信息');
      return;
    }

    setLoading(true);
    try {
      const result = await createRole({
        role_key: formData.role_key,
        role_name: formData.role_name,
        description: formData.description,
        data_scope: formData.data_scope,
        priority: formData.priority,
        is_system_role: false
      });

      if (result.success) {
        toastService.success(result.message);
        resetForm();
        onSuccess();
        onClose();
      } else {
        toastService.error(result.message);
      }
    } catch (error) {
      toastService.error('创建角色失败');
      console.error('创建角色失败:', error);
    } finally {
      setLoading(false);
    }
  };

  // 关闭时重置表单
  const handleClose = () => {
    resetForm();
    onClose();
  };

  return (
    <Modal
      isOpen={isOpen}
      onClose={handleClose}
      title="创建新角色"
      size="medium"
      footer={
        <>
          <Button type="default" onClick={handleClose} disabled={loading}>
            取消
          </Button>
          <Button type="primary" onClick={handleSubmit} disabled={loading}>
            {loading ? '创建中...' : '创建'}
          </Button>
        </>
      }
    >
      <form className="role-form" onSubmit={handleSubmit}>
        <div className="form-group">
          <label className="required">角色标识</label>
          <input
            type="text"
            className={`form-input ${errors.role_key ? 'error' : ''}`}
            placeholder="如: department_leader"
            value={formData.role_key}
            onChange={(e) => {
              const value = e.target.value;
              setFormData({ ...formData, role_key: value });

              // 实时验证
              if (value && !/^[a-z][a-z0-9_]*$/.test(value)) {
                setErrors({ ...errors, role_key: '必须以字母开头，只能包含小写字母、数字、下划线' });
              } else {
                setErrors({ ...errors, role_key: '' });
              }
            }}
            disabled={loading}
          />
          {errors.role_key && <span className="form-error">{errors.role_key}</span>}
          <span className="form-hint">必须以字母开头，只能包含小写字母、数字、下划线，创建后不可修改</span>
        </div>

        <div className="form-group">
          <label className="required">角色名称</label>
          <input
            type="text"
            className={`form-input ${errors.role_name ? 'error' : ''}`}
            placeholder="如: 部门负责人"
            value={formData.role_name}
            onChange={(e) => {
              setFormData({ ...formData, role_name: e.target.value });
              setErrors({ ...errors, role_name: '' });
            }}
            disabled={loading}
          />
          {errors.role_name && <span className="form-error">{errors.role_name}</span>}
        </div>

        <div className="form-group">
          <label>角色描述</label>
          <textarea
            className="form-textarea"
            placeholder="描述角色的职责和权限范围"
            value={formData.description}
            onChange={(e) => setFormData({ ...formData, description: e.target.value })}
            rows={3}
            disabled={loading}
          />
        </div>

        <div className="form-group">
          <label className="required">数据范围</label>
          <select
            className="form-select"
            value={formData.data_scope}
            onChange={(e) => setFormData({ ...formData, data_scope: e.target.value as any })}
            disabled={loading}
          >
            <option value="SELF">仅本人数据</option>
            <option value="DEPT">地市级数据</option>
            <option value="ALL">全部数据</option>
          </select>
          <span className="form-hint">控制该角色可访问的数据范围</span>
        </div>

        {/* <div className="form-group">
          <label>优先级</label>
          <input
            type="number"
            className="form-input"
            placeholder="数字越小优先级越高"
            value={formData.priority}
            onChange={(e) => setFormData({ ...formData, priority: parseInt(e.target.value) || 10 })}
            min={1}
            max={100}
            disabled={loading}
          />
          <span className="form-hint">数字越小优先级越高，范围 1-100</span>
        </div> */}
      </form>
    </Modal>
  );
}

// ==================== 编辑角色模态框 ====================

interface EditRoleModalProps {
  isOpen: boolean;
  onClose: () => void;
  onSuccess: () => void;
  role: RoleInfo | null;
}

function EditRoleModal({ isOpen, onClose, onSuccess, role }: EditRoleModalProps) {
  const [formData, setFormData] = useState({
    role_name: '',
    description: '',
    data_scope: 'SELF' as 'ALL' | 'DEPT' | 'SELF',
    priority: 10
  });

  const [loading, setLoading] = useState(false);
  const [errors, setErrors] = useState<Record<string, string>>({});

  // 当角色数据变化时，更新表单
  useEffect(() => {
    if (role && isOpen) {
      setFormData({
        role_name: role.role_name,
        description: role.description || '',
        data_scope: role.data_scope as any,
        priority: role.priority
      });
      setErrors({});
    }
  }, [role, isOpen]);

  // 验证表单
  const validateForm = (): boolean => {
    const newErrors: Record<string, string> = {};

    if (!formData.role_name.trim()) {
      newErrors.role_name = '角色名称不能为空';
    }

    setErrors(newErrors);
    return Object.keys(newErrors).length === 0;
  };

  // 提交表单
  const handleSubmit = async (e?: React.FormEvent) => {
    if (e) e.preventDefault();

    if (!role) return;

    if (!validateForm()) {
      toastService.error('请填写正确的表单信息');
      return;
    }

    setLoading(true);
    try {
      const result = await updateRole(role.id, {
        role_name: formData.role_name,
        description: formData.description,
        data_scope: formData.data_scope,
        priority: formData.priority
      });

      if (result.success) {
        toastService.success(result.message);
        onSuccess();
        onClose();
      } else {
        toastService.error(result.message);
      }
    } catch (error) {
      toastService.error('更新角色失败');
      console.error('更新角色失败:', error);
    } finally {
      setLoading(false);
    }
  };

  if (!role) return null;

  return (
    <Modal
      isOpen={isOpen}
      onClose={onClose}
      title={`编辑角色 - ${role.role_key}`}
      size="medium"
      footer={
        <>
          <Button type="default" onClick={onClose} disabled={loading}>
            取消
          </Button>
          <Button type="primary" onClick={handleSubmit} disabled={loading}>
            {loading ? '保存中...' : '保存'}
          </Button>
        </>
      }
    >
      <form className="role-form" onSubmit={handleSubmit}>
        {role.is_system_role && (
          <div className="form-notice warning">
            <i className="ri-information-line"></i>
            <span>系统角色的某些字段不可修改</span>
          </div>
        )}

        <div className="form-group">
          <label>角色标识</label>
          <input
            type="text"
            className="form-input"
            value={role.role_key}
            disabled
            style={{ background: '#f5f7fa', cursor: 'not-allowed' }}
          />
          <span className="form-hint">角色标识创建后不可修改</span>
        </div>

        <div className="form-group">
          <label className="required">角色名称</label>
          <input
            type="text"
            className={`form-input ${errors.role_name ? 'error' : ''}`}
            placeholder="如: 部门负责人"
            value={formData.role_name}
            onChange={(e) => {
              setFormData({ ...formData, role_name: e.target.value });
              setErrors({ ...errors, role_name: '' });
            }}
            disabled={loading}
          />
          {errors.role_name && <span className="form-error">{errors.role_name}</span>}
        </div>

        <div className="form-group">
          <label>角色描述</label>
          <textarea
            className="form-textarea"
            placeholder="描述角色的职责和权限范围"
            value={formData.description}
            onChange={(e) => setFormData({ ...formData, description: e.target.value })}
            rows={3}
            disabled={loading}
          />
        </div>

        <div className="form-group">
          <label className="required">数据范围</label>
          <select
            className="form-select"
            value={formData.data_scope}
            onChange={(e) => setFormData({ ...formData, data_scope: e.target.value as any })}
            disabled={loading || (role.is_system_role && role.role_key === 'provincial_admin')}
          >
            <option value="SELF">仅本人数据</option>
            <option value="DEPT">地市级数据</option>
            <option value="ALL">全部数据</option>
          </select>
          {role.is_system_role && role.role_key === 'provincial_admin' && (
            <span className="form-hint">省级管理员的数据范围不可修改</span>
          )}
        </div>

        {/* <div className="form-group">
          <label>优先级</label>
          <input
            type="number"
            className="form-input"
            placeholder="数字越小优先级越高"
            value={formData.priority}
            onChange={(e) => setFormData({ ...formData, priority: parseInt(e.target.value) || 10 })}
            min={1}
            max={100}
            disabled={loading}
          />
          <span className="form-hint">数字越小优先级越高，范围 1-100</span>
        </div> */}
      </form>
    </Modal>
  );
}

// ==================== 分配用户模态框 ====================

interface AssignUserModalProps {
  isOpen: boolean;
  onClose: () => void;
  onSuccess: () => void;
  role: RoleInfo | null;
  isCityAdmin?: boolean;
  currentUserArea?: string;
}

function AssignUserModal({ isOpen, onClose, onSuccess, role, isCityAdmin, currentUserArea }: AssignUserModalProps) {
  const [allUsers, setAllUsers] = useState<UserInfo[]>([]);
  const [selectedUserIds, setSelectedUserIds] = useState<number[]>([]);
  const [searchTerm, setSearchTerm] = useState('');
  const [loading, setLoading] = useState(false);
  const [loadingUsers, setLoadingUsers] = useState(false);
  // 存储每个用户的角色信息
  const [userRolesMap, setUserRolesMap] = useState<Map<number, RoleInfo[]>>(new Map());

  // 当模态框打开时，加载用户列表
  useEffect(() => {
    if (isOpen && role) {
      loadUsers();
    }
  }, [isOpen, role]);

  // 加载所有用户及其角色信息
  const loadUsers = async () => {
    setLoadingUsers(true);
    try {
      const users = await getAllUsers();

      // v3.3: 市级管理员只能看到同地区的用户（使用 area 字段）
      let filteredUsers = users;
      if (isCityAdmin && currentUserArea) {
        filteredUsers = users.filter(user => user.area === currentUserArea);
        console.log('🔒 [AssignUserModal v3.3] 市级管理员用户过滤:', {
          当前地区: currentUserArea,
          原始用户数: users.length,
          过滤后用户数: filteredUsers.length
        });
      }

      setAllUsers(filteredUsers);

      // 批量获取每个用户的角色
      const rolesMap = new Map<number, RoleInfo[]>();
      await Promise.all(
        filteredUsers.map(async (user) => {
          const roles = await getUserRoles(user.id);
          rolesMap.set(user.id, roles);
        })
      );
      setUserRolesMap(rolesMap);
    } catch (error) {
      console.error('加载用户列表失败:', error);
      toastService.error('加载用户列表失败');
    } finally {
      setLoadingUsers(false);
    }
  };

  // 重置状态
  const resetState = () => {
    setSelectedUserIds([]);
    setSearchTerm('');
  };

  // 提交分配
  const handleSubmit = async () => {
    if (!role) return;

    if (selectedUserIds.length === 0) {
      toastService.error('请至少选择一个用户');
      return;
    }

    setLoading(true);
    try {
      // 检查每个用户是否已有角色
      const usersWithRoles: Array<{ userId: number; userName: string; roleName: string }> = [];

      for (const userId of selectedUserIds) {
        const userRoles = await getUserRoles(userId);
        if (userRoles.length > 0) {
          const user = allUsers.find(u => u.id === userId);
          usersWithRoles.push({
            userId,
            userName: user?.nick_name || user?.username || `用户${userId}`,
            roleName: userRoles.map(r => r.role_name).join('、')
          });
        }
      }

      // 如果有用户已经有角色，阻止分配并提示
      if (usersWithRoles.length > 0) {
        const userList = usersWithRoles.map(u => `• ${u.userName} (当前角色: ${u.roleName})`).join('\n');
        toastService.error(
          `以下用户已有角色，不能同时拥有多个角色：\n${userList}\n\n请先移除其现有角色后再分配新角色。`
        );
        setLoading(false);
        return;
      }

      // 为每个选中的用户分配角色
      const promises = selectedUserIds.map(userId =>
        assignUserRoles(userId, [role.id])
      );

      const results = await Promise.all(promises);

      // v3.4: 检查是否有失败的
      const failedResults = results.filter(r => !r.success);
      if (failedResults.length > 0) {
        // 如果有失败的，显示第一个错误消息
        const firstError = failedResults[0];
        toastService.error(firstError.message);
        setLoading(false);
        return;
      }

      // 全部成功
      toastService.success(`成功为 ${selectedUserIds.length} 个用户分配角色`);
      resetState();
      onSuccess();
      onClose();
    } catch (error) {
      console.error('分配用户角色失败:', error);
      toastService.error('分配用户角色失败');
    } finally {
      setLoading(false);
    }
  };

  // 关闭时重置
  const handleClose = () => {
    resetState();
    onClose();
  };

  // 全选/取消全选
  const handleToggleAll = () => {
    const filteredUserIds = filteredUsers.map(u => u.id);
    if (selectedUserIds.length === filteredUserIds.length) {
      setSelectedUserIds([]);
    } else {
      setSelectedUserIds(filteredUserIds);
    }
  };

  if (!role) return null;

  // 过滤用户
  const filteredUsers = allUsers.filter(user => {
    const searchLower = searchTerm.toLowerCase();
    return (
      user.nick_name.toLowerCase().includes(searchLower) ||
      user.username.toLowerCase().includes(searchLower) ||
      user.ou_name.toLowerCase().includes(searchLower)
    );
  });

  return (
    <Modal
      isOpen={isOpen}
      onClose={handleClose}
      title={`为角色"${role.role_name}"分配用户`}
      size="medium"
      footer={
        <>
          <Button type="default" onClick={handleClose} disabled={loading}>
            取消
          </Button>
          <Button type="primary" onClick={handleSubmit} disabled={loading || selectedUserIds.length === 0}>
            {loading ? '分配中...' : `分配 (${selectedUserIds.length})`}
          </Button>
        </>
      }
    >
      <div className="assign-user-modal">
        {/* v3.3: 市级管理员地区过滤提示 */}
        {isCityAdmin && currentUserArea && (
          <div className="form-notice info" style={{ marginBottom: '12px' }}>
            <i className="ri-information-line"></i>
            <span>市级管理员权限：仅显示 {currentUserArea} 地区的用户</span>
          </div>
        )}

        {/* 搜索框 */}
        <div className="search-box">
          <i className="ri-search-line"></i>
          <input
            type="text"
            placeholder="搜索用户（姓名、用户名、单位）"
            value={searchTerm}
            onChange={(e) => setSearchTerm(e.target.value)}
          />
        </div>

        {/* 全选按钮 */}
        <div className="select-all-bar">
          <label className="user-checkbox-item select-all">
            <input
              type="checkbox"
              checked={filteredUsers.length > 0 && selectedUserIds.length === filteredUsers.length}
              onChange={handleToggleAll}
              disabled={filteredUsers.length === 0}
            />
            <span className="user-name">
              全选 ({selectedUserIds.length} / {filteredUsers.length})
            </span>
          </label>
        </div>

        {/* 用户复选框列表 */}
        {loadingUsers ? (
          <div className="loading-container" style={{ minHeight: '300px' }}>
            <i className="ri-loader-4-line spin"></i>
            <span>加载用户中...</span>
          </div>
        ) : (
          <div className="users-checkbox-list" style={{ maxHeight: '400px', minHeight: '400px', overflow: 'auto' }}>
            {filteredUsers.length > 0 ? (
              filteredUsers.map(user => {
                const userRoles = userRolesMap.get(user.id) || [];
                const hasRoles = userRoles.length > 0;

                return (
                  <label key={user.id} className="user-checkbox-item">
                    <input
                      type="checkbox"
                      checked={selectedUserIds.includes(user.id)}
                      onChange={(e) => {
                        if (e.target.checked) {
                          setSelectedUserIds([...selectedUserIds, user.id]);
                        } else {
                          setSelectedUserIds(selectedUserIds.filter(id => id !== user.id));
                        }
                      }}
                    />
                    <div className="user-info">
                      <div className="user-name">
                        {user.nick_name}
                        {user.is_leader && (
                          <span className="leader-badge" style={{ marginLeft: '8px' }}>负责人</span>
                        )}
                        {hasRoles && (
                          <span
                            className="role-badge"
                            style={{
                              marginLeft: '8px',
                              padding: '2px 8px',
                              fontSize: '12px',
                              backgroundColor: '#f0f9ff',
                              color: '#0284c7',
                              border: '1px solid #bae6fd',
                              borderRadius: '4px'
                            }}
                            title={`当前角色: ${userRoles.map(r => r.role_name).join('、')}`}
                          >
                            {userRoles.map(r => r.role_name).join('、')}
                          </span>
                        )}
                      </div>
                      <div className="user-meta">
                        @{user.username} • {user.ou_name}
                        {user.area && ` • ${user.area}`}
                        {user.phone_number && ` • ${user.phone_number}`}
                      </div>
                    </div>
                  </label>
                );
              })
            ) : (
              <div className="empty-state" style={{ padding: '40px 20px' }}>
                <i className="ri-user-search-line"></i>
                <p>{searchTerm ? '没有找到匹配的用户' : '没有可分配的用户'}</p>
              </div>
            )}
          </div>
        )}
      </div>
    </Modal>
  );
}

// 主组件
export default function RolePermissions() {
  const [roles, setRoles] = useState<RoleInfo[]>([]);
  const [routes, setRoutes] = useState<RouteInfo[]>([]);
  const [users, setUsers] = useState<UserInfo[]>([]);
  const [selectedRole, setSelectedRole] = useState<RoleInfo | null>(null);
  const [activeTab, setActiveTab] = useState<'permissions' | 'users'>('permissions');
  const [loading, setLoading] = useState(true);

  // v3.3: 检查当前用户角色和地区
  const [currentUserRole, setCurrentUserRole] = useState('');
  const [currentUserArea, setCurrentUserArea] = useState('');
  const [isProvincialAdmin, setIsProvincialAdmin] = useState(false);
  const [isCityAdmin, setIsCityAdmin] = useState(false);

  // 模态框状态
  const [showCreateModal, setShowCreateModal] = useState(false);
  const [showEditModal, setShowEditModal] = useState(false);
  const [roleToEdit, setRoleToEdit] = useState<RoleInfo | null>(null);
  const [showAssignUserModal, setShowAssignUserModal] = useState(false);

  // 确认删除Modal状态
  const [showDeleteConfirm, setShowDeleteConfirm] = useState(false);
  const [deleteTarget, setDeleteTarget] = useState<{
    type: 'role' | 'userRole';
    role?: RoleInfo;
    user?: UserInfo;
    userCount?: number;  // 删除角色时，关联的用户数量
  } | null>(null);
  const [deleteCountdown, setDeleteCountdown] = useState(3);

  // 权限警告Modal状态
  const [showPermissionWarning, setShowPermissionWarning] = useState(false);
  const [pendingRouteChange, setPendingRouteChange] = useState<{
    routeId: number;
    checked: boolean;
  } | null>(null);

  // 路由权限相关状态
  const [selectedRouteIds, setSelectedRouteIds] = useState<number[]>([]);
  const [roleUsers, setRoleUsers] = useState<UserInfo[]>([]);

  // v3.0: API权限相关状态
  const [selectedPermissionIds, setSelectedPermissionIds] = useState<number[]>([]);
  const [expandedRouteIds, setExpandedRouteIds] = useState<number[]>([]);
  // 存储每个路由的 permissions（routeId -> permissions[]）
  const [routePermissionsMap, setRoutePermissionsMap] = useState<Map<number, ApiPermission[]>>(new Map());

  // v3.9: 父子路由折叠状态（存储已展开的父路由ID）
  const [collapsedRouteIds, setCollapsedRouteIds] = useState<number[]>([]);

  // 保存权限的 loading 状态
  const [savingPermissions, setSavingPermissions] = useState(false);

  // v3.8: 加载角色权限的 loading 状态
  const [loadingPermissions, setLoadingPermissions] = useState(false);

  // v3.8: 路由ID到路由信息的映射（用于显示通用权限关联的路由名称）
  const [routeIdToInfoMap, setRouteIdToInfoMap] = useState<Map<number, { title: string; path: string }>>(new Map());

  // 加载初始数据
  useEffect(() => {
    loadData();
  }, []);

  // 删除确认倒计时
  useEffect(() => {
    let timer: NodeJS.Timeout;
    if (showDeleteConfirm && deleteCountdown > 0) {
      timer = setTimeout(() => {
        setDeleteCountdown(deleteCountdown - 1);
      }, 1000);
    }
    return () => clearTimeout(timer);
  }, [showDeleteConfirm, deleteCountdown]);

  const loadData = async () => {
    setLoading(true);
    try {
      // v3.3: 检查当前用户角色和地区
      if (typeof window !== 'undefined') {
        const userInfoStr = localStorage.getItem('user_info');
        if (userInfoStr) {
          try {
            const userInfo = JSON.parse(userInfoStr);
            const userRole = userInfo.user_role || '';
            const userArea = userInfo.area || '';  // v3.3: 使用 area 字段进行地区隔离

            setCurrentUserRole(userRole);
            setCurrentUserArea(userArea);
            setIsProvincialAdmin(userRole === 'provincial_admin');
            setIsCityAdmin(userRole === 'admin');

            console.log('🔑 [RolePermissions v3.3] 当前用户信息:', {
              role: userRole,
              area: userArea,
              isProvincialAdmin: userRole === 'provincial_admin',
              isCityAdmin: userRole === 'admin'
            });
          } catch (e) {
            console.error('❌ [RolePermissions] 解析用户信息失败:', e);
          }
        }
      }

      const [rolesData, routesData, usersData] = await Promise.all([
        getRoles(),
        getRoutes(),
        getAllUsers()
      ]);

      // v3.3: 角色列表对所有人可见（不过滤）
      const filteredRoles = rolesData;

      // v3.3: 根据用户地区过滤可见的用户列表
      const filteredUsers = usersData;
      // let filteredUsers = usersData;
      // if (isCityAdmin && currentUserArea) {
      //   // 市级管理员只能看到同地区的用户（使用 area 字段）
      //   filteredUsers = usersData.filter(user =>
      //     user.area === currentUserArea
      //   );
      //   console.log('🔒 [RolePermissions v3.3] 市级管理员用户过滤:', {
      //     当前地区: currentUserArea,
      //     原始用户数: usersData.length,
      //     过滤后用户数: filteredUsers.length
      //   });
      // }

      setRoles(filteredRoles);
      setRoutes(routesData);
      setUsers(filteredUsers);

      // v3.8: 构建路由ID到路由信息的映射
      const buildRouteIdMap = (routes: RouteInfo[]): Map<number, { title: string; path: string }> => {
        const map = new Map<number, { title: string; path: string }>();
        const traverse = (routeList: RouteInfo[]) => {
          routeList.forEach(route => {
            map.set(route.id, { title: route.route_title, path: route.route_path });
            if (route.children) {
              traverse(route.children);
            }
          });
        };
        traverse(routes);
        return map;
      };
      setRouteIdToInfoMap(buildRouteIdMap(routesData));

      // 默认选中第一个角色（使用过滤后的列表）
      if (filteredRoles.length > 0) {
        handleSelectRole(filteredRoles[0]);
      }
    } catch (error) {
      console.error("加载数据失败:", error);
      toastService.error("加载数据失败");
    } finally {
      setLoading(false);
    }
  };

  // ==================== 权限状态管理 ====================
  // 存储原始的、未映射的权限（用于保存时）
  const [originalRoutePermissionsMap, setOriginalRoutePermissionsMap] = useState<Map<number, ApiPermission[]>>(new Map());
  const [originalAllPermissions, setOriginalAllPermissions] = useState<ApiPermission[]>([]);

  // 选择角色
  const handleSelectRole = async (role: RoleInfo) => {
    setSelectedRole(role);
    setLoadingPermissions(true);  // v3.8: 开始加载权限

    try {
      // 动态导入权限映射工具
      const { mapPermissions } = await import('~/utils/permission-mapper');

      // v3.0: 并行加载数据
      const [routesResult, rolePermissions, users] = await Promise.all([
        getRoleRoutesWithPermissions(role.id),
        getRolePermissions(role.id),  // 获取该角色已分配的权限
        getRoleUsers(role.id)
      ]);

      const { routes: routesWithPerms, selectedRouteIds: routeIds } = routesResult;

      // v3.6: 为每个路由获取权限（包含通用权限）
      // 收集所有路由ID
      const collectAllRouteIds = (routes: RouteInfo[]): number[] => {
        let ids: number[] = [];
        routes.forEach(route => {
          ids.push(route.id);
          if (route.children) {
            ids = ids.concat(collectAllRouteIds(route.children));
          }
        });
        return ids;
      };

      const allRouteIds = collectAllRouteIds(routesWithPerms);

      // v3.6: 并行获取每个路由的权限（包含通用权限）
      const routePermissionsPromises = allRouteIds.map(async (routeId) => {
        const permissions = await getRoutePermissions(routeId);
        return { routeId, permissions };
      });

      const routePermissionsResults = await Promise.all(routePermissionsPromises);

      // 构建原始权限映射（用于保存）
      const originalPermMap = new Map<number, ApiPermission[]>();
      const allOriginalPerms: ApiPermission[] = [];
      // 用于去重通用权限（通用权限可能在多个路由下出现，但只需要保存一次）
      const seenPermissionIds = new Set<number>();

      routePermissionsResults.forEach(({ routeId, permissions }) => {
        if (permissions.length > 0) {
          originalPermMap.set(routeId, permissions);
          permissions.forEach(p => {
            if (!seenPermissionIds.has(p.id)) {
              seenPermissionIds.add(p.id);
              allOriginalPerms.push(p);
            }
          });
        }
      });

      // 存储原始权限
      setOriginalRoutePermissionsMap(originalPermMap);
      setOriginalAllPermissions(allOriginalPerms);

      // 构建映射后的权限映射（用于显示）
      const displayPermMap = new Map<number, ApiPermission[]>();
      routePermissionsResults.forEach(({ routeId, permissions }) => {
        if (permissions.length > 0) {
          const mappedPermissions = mapPermissions(permissions) as ApiPermission[];
          displayPermMap.set(routeId, mappedPermissions);
        }
      });

      // v3.5: 修复BUG - 只筛选 grant_type=GRANT 的权限
      // BUG说明：之前没有检查 grant_type，导致 DENY 的权限也被显示为勾选
      // 修改前：const assignedPermissionIds = rolePermissions.map(p => p.permission_id);
      const assignedPermissionIds = rolePermissions
        .filter(p => p.grant_type === 'GRANT')
        .map(p => p.permission_id);

      // console.log('🔑 [RolePermissions v3.0] 过滤前的已分配权限ID长度:', rolePermissions);

      // 存储状态
      setRoutePermissionsMap(displayPermMap); // 用于显示
      setSelectedRouteIds(routeIds);
      setSelectedPermissionIds(assignedPermissionIds); // 使用原始权限ID
      setExpandedRouteIds([]); // 重置展开状态
      setRoleUsers(users);
    } catch (error) {
      console.error('加载角色权限失败:', error);
      toastService.error('加载角色权限失败');
    } finally {
      setLoadingPermissions(false);  // v3.8: 结束加载权限
    }
  };

  // 递归查找路由
  const findRouteById = (routes: RouteInfo[], routeId: number): RouteInfo | null => {
    for (const route of routes) {
      if (route.id === routeId) {
        return route;
      }
      if (route.children && route.children.length > 0) {
        const found = findRouteById(route.children, routeId);
        if (found) return found;
      }
    }
    return null;
  };

  // 递归获取所有路由ID（包括子路由）
  const getAllRouteIds = (routes: RouteInfo[]): number[] => {
    let ids: number[] = [];
    routes.forEach(route => {
      ids.push(route.id);
      if (route.children && route.children.length > 0) {
        ids = ids.concat(getAllRouteIds(route.children));
      }
    });
    return ids;
  };

  // 递归检查路由树中是否包含指定路径的路由
  const containsRoutePath = (routes: RouteInfo[], targetPath: string): boolean => {
    for (const route of routes) {
      if (route.route_path === targetPath) {
        return true;
      }
      if (route.children && route.children.length > 0) {
        if (containsRoutePath(route.children, targetPath)) {
          return true;
        }
      }
    }
    return false;
  };

  // 切换路由权限
  const handleToggleRoute = (routeId: number, checked: boolean) => {
    // 检查是否正在取消勾选 /role-permissions 路由
    if (!checked) {
      const route = findRouteById(routes, routeId);
      if (route && route.route_path === '/role-permissions') {
        // 显示警告模态框
        setPendingRouteChange({ routeId, checked });
        setShowPermissionWarning(true);
        return;
      }
    }

    if (checked) {
      setSelectedRouteIds([...selectedRouteIds, routeId]);
    } else {
      setSelectedRouteIds(selectedRouteIds.filter(id => id !== routeId));
    }
  };

  // 切换父路由（包括所有子路由）
  const handleToggleParentRoute = (route: RouteInfo, checked: boolean) => {
    // 检查是否正在取消勾选包含 /role-permissions 的父路由
    if (!checked) {
      const allRoutes = route.children ? [route, ...route.children] : [route];
      const hasRolePermissionsRoute = allRoutes.some(r => r.route_path === '/role-permissions') ||
                                       (route.children && containsRoutePath(route.children, '/role-permissions'));

      if (route.route_path === '/role-permissions' || hasRolePermissionsRoute) {
        // 显示警告模态框，传递 route 对象表示是父路由操作
        setPendingRouteChange({ routeId: route.id, checked });
        setShowPermissionWarning(true);
        return;
      }
    }

    const childIds = route.children ? getAllRouteIds(route.children) : [];
    const allIds = [route.id, ...childIds];

    if (checked) {
      const newIds = [...selectedRouteIds, ...allIds].filter(
        (id, index, self) => self.indexOf(id) === index
      );
      setSelectedRouteIds(newIds);
    } else {
      setSelectedRouteIds(
        selectedRouteIds.filter(id => !allIds.includes(id))
      );
    }
  };

  // 确认取消角色权限管理路由
  const confirmRemovePermissionRoute = () => {
    if (!pendingRouteChange) return;

    const { routeId, checked } = pendingRouteChange;
    const route = findRouteById(routes, routeId);

    if (route) {
      // 如果是父路由，取消所有子路由
      if (route.children && route.children.length > 0) {
        const childIds = getAllRouteIds(route.children);
        const allIds = [route.id, ...childIds];
        setSelectedRouteIds(selectedRouteIds.filter(id => !allIds.includes(id)));
      } else {
        // 单个路由
        setSelectedRouteIds(selectedRouteIds.filter(id => id !== routeId));
      }
    }

    // 关闭模态框并重置状态
    setShowPermissionWarning(false);
    setPendingRouteChange(null);

    toastService.warning('已取消角色权限管理路由，请谨慎保存权限配置');
  };

  // v3.0: 切换路由展开状态（显示/隐藏权限列表）
  const handleToggleRouteExpand = (routeId: number) => {
    setExpandedRouteIds(prev =>
      prev.includes(routeId)
        ? prev.filter(id => id !== routeId)
        : [...prev, routeId]
    );
  };

  // v3.9: 切换父子路由折叠状态
  const handleToggleCollapse = (routeId: number) => {
    setCollapsedRouteIds(prev =>
      prev.includes(routeId)
        ? prev.filter(id => id !== routeId)
        : [...prev, routeId]
    );
  };

  // v3.9: 全部展开/全部折叠
  const handleExpandAll = () => {
    setCollapsedRouteIds([]);
  };

  const handleCollapseAll = () => {
    // 收集所有有子路由的路由ID
    const collectParentRouteIds = (routeList: RouteInfo[]): number[] => {
      let ids: number[] = [];
      routeList.forEach(route => {
        if (route.children && route.children.length > 0) {
          ids.push(route.id);
          ids = ids.concat(collectParentRouteIds(route.children));
        }
      });
      return ids;
    };
    setCollapsedRouteIds(collectParentRouteIds(routes));
  };

  // v3.0: 判断是否是"所有权限"项（用于过滤）
  const isAllPermission = (permission: ApiPermission): boolean => {
    const key = permission.permission_key?.toLowerCase() || '';
    const name = permission.display_name || '';
    return key.includes(':all:') || key.includes(':*:') ||
           key.endsWith(':all') || key.endsWith(':*') ||
           name.includes('所有权限') || name.includes('全部权限');
  };

  // v3.0: 过滤掉"所有权限"项
  const filterPermissions = (permissions: ApiPermission[]): ApiPermission[] => {
    return permissions.filter(p => !isAllPermission(p));
  };

  // v3.7: 切换单个API权限（支持通用权限同步）
  const handleTogglePermission = (permission: ApiPermission, checked: boolean) => {
    const permissionId = permission.id;

    if (checked) {
      setSelectedPermissionIds([...selectedPermissionIds, permissionId]);
    } else {
      setSelectedPermissionIds(selectedPermissionIds.filter(id => id !== permissionId));
    }

    // v3.7: 如果是通用权限，同步更新其他关联路由的显示状态
    // 注意：由于通用权限在数据库中只有一条记录，这里只需要更新 UI 显示
    // 实际的 selectedPermissionIds 只需要包含一次该权限ID
    if (isSharedPermission(permission) && permission.related_routes) {
      // 通用权限的 permissionId 是唯一的，所以这里不需要额外处理
      // 但需要触发 UI 更新，让其他路由下显示的同一权限也更新勾选状态
      // 由于 React 的状态更新机制，上面的 setSelectedPermissionIds 已经会触发重渲染
      console.log(`🔗 [handleTogglePermission] 通用权限 ${permission.display_name} 已${checked ? '勾选' : '取消'}，关联路由: ${permission.related_routes.join(', ')}`);
    }
  };

  // v3.0: 获取HTTP方法对应的标签样式
  const getMethodTagStyle = (method: string | null | undefined): React.CSSProperties => {
    const styles: Record<string, React.CSSProperties> = {
      'GET': { backgroundColor: '#e6f7ed', color: '#52c41a', border: '1px solid #b7eb8f' },
      'POST': { backgroundColor: '#e6f0ff', color: '#1890ff', border: '1px solid #91caff' },
      'PUT': { backgroundColor: '#fff7e6', color: '#faad14', border: '1px solid #ffd591' },
      'DELETE': { backgroundColor: '#fff1f0', color: '#f5222d', border: '1px solid #ffa39e' },
      'PATCH': { backgroundColor: '#f0f5ff', color: '#722ed1', border: '1px solid #d3adf7' }
    };

    // 空值检查：如果 method 为 null 或 undefined，返回默认样式
    if (!method) {
      return { backgroundColor: '#f5f5f5', color: '#666', border: '1px solid #d9d9d9' };
    }

    return styles[method.toUpperCase()] || { backgroundColor: '#f5f5f5', color: '#666', border: '1px solid #d9d9d9' };
  };

  // 编辑角色
  const handleEditRole = (role: RoleInfo) => {
    setRoleToEdit(role);
    setShowEditModal(true);
  };

  // 删除角色 - 显示确认Modal
  const handleDeleteRole = async (role: RoleInfo) => {
    // 系统角色禁止删除
    if (role.is_system_role) {
      toastService.error('系统角色不能删除');
      return;
    }

    // 核心角色保护
    const coreRoles = ['provincial_admin', 'admin', 'common'];
    if (coreRoles.includes(role.role_key)) {
      toastService.error('系统核心角色不能删除');
      return;
    }

    // 获取该角色关联的用户数量
    const users = await getRoleUsers(role.id);
    const userCount = users.length;

    // 打开确认删除Modal
    setDeleteTarget({ type: 'role', role, userCount });
    setDeleteCountdown(3);
    setShowDeleteConfirm(true);
  };

  // 确认删除角色 - 实际执行删除
  const confirmDeleteRole = async () => {
    if (!deleteTarget || deleteTarget.type !== 'role' || !deleteTarget.role) return;

    const role = deleteTarget.role;
    const userCount = deleteTarget.userCount || 0;
    setShowDeleteConfirm(false);
    setDeleteTarget(null);

    try {
      const result = await deleteRole(role.id, false);

      if (result.success) {
        // 根据是否有用户解绑，显示不同的成功提示
        if (userCount > 0) {
          toastService.success(`角色删除成功，已自动解除 ${userCount} 个用户的角色绑定`);
        } else {
          toastService.success(result.message);
        }
        // 重新加载数据
        await loadData();
        // 如果删除的是当前选中的角色，清除选中状态
        if (selectedRole?.id === role.id) {
          setSelectedRole(null);
        }
      } else {
        toastService.error(result.message);
      }
    } catch (error) {
      console.error('删除角色失败:', error);
      toastService.error('删除角色失败');
    }
  };

  // 移除用户角色 - 显示确认Modal
  const handleRemoveUserRole = (user: UserInfo) => {
    if (!selectedRole) return;

    // 打开确认删除Modal
    setDeleteTarget({ type: 'userRole', role: selectedRole, user });
    setDeleteCountdown(3);
    setShowDeleteConfirm(true);
  };

  // 确认移除用户角色 - 实际执行
  const confirmRemoveUserRole = async () => {
    if (!deleteTarget || deleteTarget.type !== 'userRole' || !deleteTarget.role || !deleteTarget.user) return;

    const { role, user } = deleteTarget;
    setShowDeleteConfirm(false);
    setDeleteTarget(null);

    try {
      const result = await revokeUserRole(user.id, role.id);

      if (result.success) {
        toastService.success(result.message);
        // 重新加载该角色的用户列表
        const users = await getRoleUsers(role.id);
        setRoleUsers(users);
      } else {
        toastService.error(result.message);
      }
    } catch (error) {
      console.error('移除用户角色失败:', error);
      toastService.error('移除用户角色失败');
    }
  };

  // 保存权限 - v3.3: 同时保存路由权限和API权限，仅省级管理员可操作
  // v3.5: 增加事务性操作和回滚机制
  const handleSavePermissions = async () => {
    if (!selectedRole) return;

    // v3.3: 前置权限检查（仅省级管理员）
    if (!isProvincialAdmin) {
      toastService.error('权限不足：仅省级管理员可以修改角色路由权限');
      return;
    }

    setSavingPermissions(true);

    // v3.5: 开始事务性操作，保存原始状态以便回滚
    const originalRouteIds = [...selectedRouteIds];
    const originalPermissionIds = [...selectedPermissionIds];

    try {
      // 1. 保存路由权限
      const routeResult = await updateRoleRoutePermissions(selectedRole.id, selectedRouteIds);

      // v3.3: 处理权限不足错误
      if (!routeResult.success) {
        if (routeResult.code === 4003) {
          toastService.error('权限不足：仅省级管理员可以修改角色路由权限');
        } else {
          toastService.error(routeResult.message);
        }
        return;
      }

      // v3.5: 只有在路由权限保存成功后才保存API权限
      // 2. 保存API权限（如果有选中的权限）
      let permResult;
      if (selectedPermissionIds.length > 0) {
        permResult = await saveRoleApiPermissions(selectedRole.id, selectedPermissionIds);
      } else {
        // 没有选中API权限时，清空该角色的所有API权限
        permResult = await saveRoleApiPermissions(selectedRole.id, []);
      }

      // v3.5: 处理API权限保存失败的情况
      if (!permResult.success) {
        console.error('API权限保存失败，正在回滚路由权限...');
        // 回滚路由权限到原始状态
        await updateRoleRoutePermissions(selectedRole.id, originalRouteIds);
        toastService.error('权限保存失败，已自动回滚到原始状态');
        // 恢复前端状态
        setSelectedRouteIds(originalRouteIds);
        setSelectedPermissionIds(originalPermissionIds);
        return;
      }

      toastService.success(`路由权限：${routeResult.message} | API权限：${permResult.message}`);
    } catch (error) {
      console.error("保存权限失败:", error);
      toastService.error("保存权限失败，已自动回滚到原始状态");
      // 发生异常时回滚到原始状态
      setSelectedRouteIds(originalRouteIds);
      setSelectedPermissionIds(originalPermissionIds);
    } finally {
      setSavingPermissions(false);
    }
  };

  // v3.8: 渲染路由树 - 卡片式设计，支持展开显示API权限
  const renderRouteTree = (routeList: RouteInfo[], level = 0) => {
    return routeList.map(route => {
      const hasChildren = route.children && route.children.length > 0;
      // 从 routePermissionsMap 获取该路由的 permissions，并过滤掉"所有权限"
      const rawPermissions = routePermissionsMap.get(route.id) || [];
      const permissions = filterPermissions(rawPermissions);
      const hasPermissions = permissions.length > 0;
      const isChecked = selectedRouteIds.includes(route.id);
      const isExpanded = expandedRouteIds.includes(route.id);
      const allChildIds = hasChildren ? getAllRouteIds(route.children!) : [];
      const checkedChildCount = allChildIds.filter(id =>
        selectedRouteIds.includes(id)
      ).length;
      const isIndeterminate =
        hasChildren && checkedChildCount > 0 && checkedChildCount < allChildIds.length;

      // 计算该路由下已选中的权限数量（使用过滤后的权限）
      const routePermissionIds = permissions.map(p => p.id);
      const selectedPermCount = routePermissionIds.filter(id =>
        selectedPermissionIds.includes(id)
      ).length;

      // 是否为一级路由（使用卡片样式）
      const isTopLevel = level === 0;

      // 渲染权限展开按钮
      const renderPermissionButton = () => {
        if (!hasPermissions) return null;

        const btnStyle: React.CSSProperties = {
          backgroundColor:
            selectedPermCount === permissions.length ? '#e6f7ed' :
            selectedPermCount > 0 ? '#fff7e6' : '#f5f5f5',
          color:
            selectedPermCount === permissions.length ? '#52c41a' :
            selectedPermCount > 0 ? '#fa8c16' : '#666',
          border:
            selectedPermCount === permissions.length ? '1px solid #b7eb8f' :
            selectedPermCount > 0 ? '1px solid #ffd591' : '1px solid #d9d9d9',
        };

        return (
          <button
            type="button"
            className="permission-expand-btn"
            onClick={(e) => {
              e.stopPropagation();
              handleToggleRouteExpand(route.id);
            }}
            style={btnStyle}
          >
            <i className={`ri-${isExpanded ? 'arrow-up-s' : 'arrow-down-s'}-line`}></i>
            <span>API权限 ({selectedPermCount}/{permissions.length})</span>
          </button>
        );
      };

      // 渲染API权限列表
      const renderPermissionsList = () => {
        if (!hasPermissions || !isExpanded) return null;

        return (
          <div className="permissions-list">
            {permissions.map(permission => {
              const isShared = isSharedPermission(permission);

              // 获取通用权限关联的路由名称（排除当前路由）
              const relatedRouteNames = (() => {
                if (!isShared || !permission.related_routes) return [];
                return permission.related_routes
                  .filter(rid => rid !== route.id)
                  .map(rid => {
                    const routeInfo = routeIdToInfoMap.get(rid);
                    return routeInfo ? routeInfo.title : `路由${rid}`;
                  });
              })();

              return (
                <label
                  key={permission.id}
                  className={`permission-item ${isShared ? 'shared' : ''}`}
                >
                  <input
                    type="checkbox"
                    checked={selectedPermissionIds.includes(permission.id)}
                    onChange={(e) => handleTogglePermission(permission, e.target.checked)}
                    style={{ margin: '3px 0 0 0', flexShrink: 0 }}
                    disabled={!isProvincialAdmin}
                  />
                  {isShared && (
                    <span
                      className="shared-badge"
                      title={`此权限同时适用于 ${permission.related_routes?.length || 0} 个页面`}
                    >
                      通用
                    </span>
                  )}
                  <span
                    className={`method-tag ${(permission.api_method || '').toLowerCase()}`}
                  >
                    {permission.api_method || 'N/A'}
                  </span>
                  <div style={{ flex: 1, minWidth: 0 }}>
                    <span style={{ color: isShared ? '#1890ff' : '#333', fontSize: '13px', fontWeight: 500 }}>
                      {permission.display_name}
                    </span>
                    {isShared && relatedRouteNames.length > 0 && (
                      <div className="related-routes">
                        <i className="ri-link"></i>
                        <span>同时关联：</span>
                        {relatedRouteNames.map((name, idx) => (
                          <span key={idx} className="related-route-tag">{name}</span>
                        ))}
                      </div>
                    )}
                  </div>
                  <span style={{ color: '#999', fontSize: '11px', flexShrink: 0, fontFamily: 'Consolas, Monaco, monospace' }}>
                    {permission.api_path}
                  </span>
                </label>
              );
            })}
          </div>
        );
      };

      // v3.9: 判断是否折叠
      const isCollapsed = collapsedRouteIds.includes(route.id);

      // v3.9: 渲染折叠按钮
      const renderCollapseButton = () => {
        if (!hasChildren) return null;
        return (
          <button
            type="button"
            className={`collapse-btn ${isCollapsed ? 'collapsed' : ''}`}
            onClick={(e) => {
              e.stopPropagation();
              handleToggleCollapse(route.id);
            }}
            title={isCollapsed ? '展开子路由' : '折叠子路由'}
          >
            <i className={`ri-arrow-${isCollapsed ? 'right' : 'down'}-s-line`}></i>
          </button>
        );
      };

      // 一级路由使用卡片样式
      if (isTopLevel) {
        return (
          <div key={route.id} className={`route-card ${isChecked ? 'checked' : ''}`}>
            <div className="route-item-content">
              {renderCollapseButton()}
              <input
                type="checkbox"
                id={`route-${route.id}`}
                checked={isChecked}
                ref={el => {
                  if (el) el.indeterminate = isIndeterminate ?? false;
                }}
                onChange={(e) => {
                  if (hasChildren) {
                    handleToggleParentRoute(route, e.target.checked);
                  } else {
                    handleToggleRoute(route.id, e.target.checked);
                  }
                }}
                className="route-checkbox"
                disabled={!isProvincialAdmin}
              />
              <label htmlFor={`route-${route.id}`} className="route-label">
                {route.icon && <i className={`${route.icon} route-icon`}></i>}
                <span className="route-title">{route.route_title}</span>
                <span className="route-path">{route.route_path}</span>
                {hasChildren && (
                  <span className="children-count">
                    {route.children!.length} 个子路由
                  </span>
                )}
              </label>
              {renderPermissionButton()}
            </div>

            {renderPermissionsList()}

            {hasChildren && (
              <div className={`route-children ${isCollapsed ? 'collapsed' : ''}`}>
                {renderRouteTree(route.children!, level + 1)}
              </div>
            )}
          </div>
        );
      }

      // 子路由使用简洁样式
      return (
        <div key={route.id} className="route-item">
          <div className={`route-item-content ${isChecked ? 'checked' : ''}`}>
            {renderCollapseButton()}
            <input
              type="checkbox"
              id={`route-${route.id}`}
              checked={isChecked}
              ref={el => {
                if (el) el.indeterminate = isIndeterminate ?? false;
              }}
              onChange={(e) => {
                if (hasChildren) {
                  handleToggleParentRoute(route, e.target.checked);
                } else {
                  handleToggleRoute(route.id, e.target.checked);
                }
              }}
              className="route-checkbox"
              disabled={!isProvincialAdmin}
            />
            <label htmlFor={`route-${route.id}`} className="route-label">
              {route.icon && <i className={`${route.icon} route-icon`}></i>}
              <span className="route-title">{route.route_title}</span>
              <span className="route-path">{route.route_path}</span>
              {hasChildren && (
                <span className="children-count">
                  {route.children!.length} 个子路由
                </span>
              )}
            </label>
            {renderPermissionButton()}
          </div>

          {renderPermissionsList()}

          {hasChildren && (
            <div className={`route-children ${isCollapsed ? 'collapsed' : ''}`}>
              {renderRouteTree(route.children!, level + 1)}
            </div>
          )}
        </div>
      );
    });
  };

  if (loading) {
    return (
      <div className="role-permissions-page">
        <div className="loading-container">
          <i className="ri-loader-4-line spin"></i>
          <span>加载中...</span>
        </div>
      </div>
    );
  }

  // ==================== 权限检查移除说明 ====================
  // 原有的客户端权限检查已移除，统一使用 root.tsx 的路由权限控制
  // 如果用户能访问到这个页面，说明已经通过了路由权限检查
  // 不再显示"无权限"提示页面

  // 如果数据为空，可能是数据加载失败，显示友好的空状态提示
  const hasNoData = roles.length === 0 && routes.length === 0 && users.length === 0 && !loading;

  // 数据加载失败提示（不是权限问题）
  if (hasNoData) {
    return (
      <div className="role-permissions-page">
        <Card className="no-data-card">
          <div className="empty-state" style={{ padding: '80px 40px' }}>
            <i className="ri-database-2-line" style={{ fontSize: '96px', color: '#dcdfe6' }}></i>
            <h2 style={{ fontSize: '24px', fontWeight: 600, color: '#303133', marginTop: '24px', marginBottom: '12px' }}>
              暂无数据
            </h2>
            <p style={{ fontSize: '16px', color: '#606266', marginBottom: '32px' }}>
              系统中暂无角色、路由或用户数据，请稍后重试或联系管理员
            </p>
            <div style={{ display: 'flex', gap: '12px', justifyContent: 'center' }}>
              <Button type="default" icon="ri-arrow-left-line" onClick={() => window.history.back()}>
                返回上一页
              </Button>
              <Button type="primary" icon="ri-home-line" onClick={() => window.location.href = '/'}>
                返回首页
              </Button>
            </div>
          </div>
        </Card>
      </div>
    );
  }

  return (
    <div className="role-permissions-page">
      {/* 页面头部 */}
      <div className="page-header">
        <h2 className="page-title">
          <i className="ri-shield-user-line"></i>
          角色权限管理
        </h2>
        {/* <div className="page-actions">
          <Button
            type="primary"
            icon="ri-add-line"
            onClick={() => setShowCreateModal(true)}
          >
            新建角色
          </Button>
        </div> */}
      </div>

      <div className="permissions-container">
        {/* 左侧：角色列表 */}
        <Card className="roles-panel" title="角色列表" bodyClassName="p-0">
          <div className="roles-list">
            {roles.map(role => (
              <div
                key={role.id}
                className={`role-item ${selectedRole?.id === role.id ? 'active' : ''}`}
                onClick={() => handleSelectRole(role)}
              >
                <div className="role-info">
                  <div className="role-header">
                    <span className="role-name">{role.role_name}</span>
                    {role.is_system_role && (
                      <span className="system-badge">系统角色</span>
                    )}
                  </div>
                  <div className="role-key">{role.role_key}</div>
                  <div className="role-desc">{role.description}</div>
                  <div className="role-meta">
                    <span className="data-scope">
                      <i className="ri-database-line"></i>
                      {getDataScopeLabel(role.data_scope)}
                    </span>
                    {/* <span className="priority">
                      <i className="ri-sort-asc"></i>
                      优先级: {role.priority}
                    </span> */}
                  </div>
                </div>
                {!role.is_system_role && (
                  <div className="role-actions">
                    <button
                      className="btn-icon"
                      onClick={(e) => {
                        e.stopPropagation();
                        handleEditRole(role);
                      }}
                      title="编辑"
                    >
                      <i className="ri-edit-line"></i>
                    </button>
                    <button
                      className="btn-icon text-error"
                      onClick={(e) => {
                        e.stopPropagation();
                        handleDeleteRole(role);
                      }}
                      title="删除"
                    >
                      <i className="ri-delete-bin-line"></i>
                    </button>
                  </div>
                )}
              </div>
            ))}
          </div>
        </Card>

        {/* 右侧：角色详情和权限设置 */}
        <div className="permissions-detail">
          {selectedRole ? (
            <>
              {/* Tab 切换 */}
              <Card className="tabs-card">
                <div className="tabs-header">
                  <button
                    className={`tab-btn ${activeTab === 'permissions' ? 'active' : ''}`}
                    onClick={() => setActiveTab('permissions')}
                  >
                    <i className="ri-shield-check-line"></i>
                    路由权限
                  </button>
                  <button
                    className={`tab-btn ${activeTab === 'users' ? 'active' : ''}`}
                    onClick={() => setActiveTab('users')}
                  >
                    <i className="ri-team-line"></i>
                    用户列表 ({roleUsers.length})
                  </button>
                </div>

                <div className="tabs-content">
                  {/* 路由权限Tab */}
                  {activeTab === 'permissions' && (
                    <div className="permissions-tab">
                      {/* v3.8: 固定头部区域 */}
                      <div className="permissions-tab-header">
                        {/* v3.3: 权限提示（仅省级管理员可修改） */}
                        {!isProvincialAdmin && (
                          <div className="form-notice warning" style={{ marginBottom: '12px' }}>
                            <i className="ri-information-line"></i>
                            <span>您当前为只读模式，仅省级管理员可以修改角色路由权限</span>
                          </div>
                        )}
                        <div className="permissions-header">
                          <h3>为角色 "{selectedRole.role_name}" 分配路由权限</h3>
                          {loadingPermissions ? (<></>) : (
                            <>
                              {/* v3.9: 折叠控制栏 */}
                              <div className="collapse-controls">
                              <button
                                type="button"
                                className="collapse-control-btn"
                                onClick={handleExpandAll}
                                title="展开全部"
                              >
                                <i className="ri-expand-diagonal-line"></i>
                                <span>展开全部</span>
                              </button>
                              <button
                                type="button"
                                className="collapse-control-btn"
                                onClick={handleCollapseAll}
                                title="折叠全部"
                              >
                                <i className="ri-contract-left-right-line"></i>
                                <span>折叠全部</span>
                              </button>
                            </div>
                            </>
                          ) }
                          
                          <Button
                            type="primary"
                            icon={savingPermissions ? "ri-loader-4-line spin" : "ri-save-line"}
                            onClick={handleSavePermissions}
                            disabled={!isProvincialAdmin || savingPermissions}
                          >
                            {savingPermissions ? '保存中...' : '保存权限'}
                          </Button>
                        </div>
                      </div>

                      {/* v3.8: 加载状态显示 */}
                      {loadingPermissions ? (
                        <div className="loading-container" style={{ minHeight: '300px', display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', gap: '12px' }}>
                          <i className="ri-loader-4-line spin" style={{ fontSize: '32px', color: '#00684a' }}></i>
                          <span style={{ color: '#666' }}>正在加载权限配置...</span>
                        </div>
                      ) : (
                        <>
                          

                          {/* v3.8: 路由树容器 - 可滚动区域 */}
                          <div className="routes-tree-container">
                            <div className="routes-tree">
                              {renderRouteTree(routes)}
                            </div>
                          </div>

                          {/* v3.0: 更新权限统计，显示路由和API权限数量 */}
                          {/* <div className="permissions-summary">
                            <i className="ri-information-line"></i>
                            已选择 <strong>{selectedRouteIds.length}</strong> 个路由权限
                            {selectedPermissionIds.length > 0 && (
                              <>
                                ，<strong>{selectedPermissionIds.length}</strong> 个API权限
                              </>
                            )}
                          </div> */}
                        </>
                      )}
                    </div>
                  )}

                  {/* 用户列表Tab */}
                  {activeTab === 'users' && (
                    <div className="users-tab">
                      <div className="users-header">
                        <h3>拥有角色 "{selectedRole.role_name}" 的用户</h3>
                        <Button
                          type="primary"
                          icon="ri-user-add-line"
                          onClick={() => setShowAssignUserModal(true)}
                        >
                          分配用户
                        </Button>
                      </div>

                      <div className="users-list">
                        {roleUsers.length > 0 ? (
                          roleUsers.map(user => (
                            <div key={user.id} className="user-card">
                              <div className="user-avatar">
                                <i className="ri-user-line"></i>
                              </div>
                              <div className="user-info">
                                <div className="user-name">
                                  {user.nick_name}
                                  {user.is_leader && (
                                    <span className="leader-badge">负责人</span>
                                  )}
                                </div>
                                <div className="user-username">@{user.username}</div>
                                <div className="user-org">
                                  {/* {JSON.stringify(user)} */}
                                  {user.ou_name}
                                  {user.area && <span style={{ marginLeft: '8px', color: '#666' }}>• {user.area}</span>}
                                </div>
                                <div className="user-contact">
                                  {user.phone_number && (
                                    <span>
                                      <i className="ri-phone-line"></i>
                                      {user.phone_number}
                                    </span>
                                  )}
                                  {user.email && (
                                    <span>
                                      <i className="ri-mail-line"></i>
                                      {user.email}
                                    </span>
                                  )}
                                </div>
                              </div>
                              <div className="user-actions">
                                <button
                                  className="btn-icon text-error"
                                  onClick={() => handleRemoveUserRole(user)}
                                  title="移除角色"
                                >
                                  <i className="ri-user-unfollow-line"></i>
                                </button>
                              </div>
                            </div>
                          ))
                        ) : (
                          <div className="empty-state">
                            <i className="ri-user-line"></i>
                            <p>暂无用户拥有此角色</p>
                          </div>
                        )}
                      </div>
                    </div>
                  )}
                </div>
              </Card>
            </>
          ) : (
            <Card>
              <div className="empty-state">
                <i className="ri-shield-line"></i>
                <p>请选择一个角色查看详情</p>
              </div>
            </Card>
          )}
        </div>
      </div>

      {/* 创建角色模态框 */}
      <CreateRoleModal
        isOpen={showCreateModal}
        onClose={() => setShowCreateModal(false)}
        onSuccess={loadData}
      />

      {/* 编辑角色模态框 */}
      <EditRoleModal
        isOpen={showEditModal}
        onClose={() => {
          setShowEditModal(false);
          setRoleToEdit(null);
        }}
        onSuccess={loadData}
        role={roleToEdit}
      />

      {/* 分配用户模态框 */}
      <AssignUserModal
        isOpen={showAssignUserModal}
        onClose={() => setShowAssignUserModal(false)}
        onSuccess={async () => {
          // 重新加载该角色的用户列表
          if (selectedRole) {
            const users = await getRoleUsers(selectedRole.id);
            setRoleUsers(users);
          }
        }}
        role={selectedRole}
        isCityAdmin={isCityAdmin}
        currentUserArea={currentUserArea}
      />

      {/* 确认删除模态框 */}
      <Modal
        isOpen={showDeleteConfirm}
        onClose={() => {
          setShowDeleteConfirm(false);
          setDeleteTarget(null);
        }}
        title={deleteTarget?.type === 'role' ? '确认删除角色' : '确认移除用户角色'}
      >
        <div style={{ padding: '20px 0' }}>
          {deleteTarget?.type === 'role' && deleteTarget.role && (
            <div>
              <p style={{ marginBottom: '16px', fontSize: '15px', lineHeight: '1.6' }}>
                您确定要删除角色 <strong>"{deleteTarget.role.role_name}"</strong> 吗？
              </p>
              {deleteTarget.userCount !== undefined && deleteTarget.userCount > 0 && (
                <p style={{
                  marginBottom: '16px',
                  color: '#ff6b00',
                  fontSize: '14px',
                  padding: '12px',
                  backgroundColor: '#fff7e6',
                  borderLeft: '3px solid #ff6b00',
                  borderRadius: '4px'
                }}>
                  ⚠️ 该角色当前关联了 <strong>{deleteTarget.userCount}</strong> 个用户，删除后将自动解除这些用户的角色绑定。
                </p>
              )}
              <p style={{ marginBottom: '16px', color: '#666', fontSize: '14px' }}>
                此操作将永久删除该角色、相关的权限配置和路由分配，且无法恢复。
              </p>
            </div>
          )}

          {deleteTarget?.type === 'userRole' && deleteTarget.role && deleteTarget.user && (
            <div>
              <p style={{ marginBottom: '16px', fontSize: '15px', lineHeight: '1.6' }}>
                您确定要移除用户 <strong>"{deleteTarget.user.nick_name}"</strong> 的角色 <strong>"{deleteTarget.role.role_name}"</strong> 吗？
              </p>
              <p style={{ marginBottom: '16px', color: '#666', fontSize: '14px' }}>
                移除后，该用户将失去此角色的所有权限。
              </p>
            </div>
          )}

          <div style={{
            display: 'flex',
            gap: '12px',
            justifyContent: 'flex-end',
            marginTop: '24px'
          }}>
            <Button
              variant="secondary"
              onClick={() => {
                setShowDeleteConfirm(false);
                setDeleteTarget(null);
              }}
            >
              取消
            </Button>
            <Button
              variant="danger"
              onClick={() => {
                if (deleteTarget?.type === 'role') {
                  confirmDeleteRole();
                } else if (deleteTarget?.type === 'userRole') {
                  confirmRemoveUserRole();
                }
              }}
              disabled={deleteCountdown > 0}
            >
              {deleteCountdown > 0 ? `确认删除 (${deleteCountdown}秒)` : '确认删除'}
            </Button>
          </div>
        </div>
      </Modal>

      {/* 权限警告模态框 */}
      <Modal
        isOpen={showPermissionWarning}
        onClose={() => {
          setShowPermissionWarning(false);
          setPendingRouteChange(null);
        }}
        title="⚠️ 警告：取消角色权限管理路由"
        size="medium"
      >
        <div style={{ padding: '20px 0' }}>
          <p style={{ marginBottom: '16px', fontSize: '15px', lineHeight: '1.6', color: '#ff6b00' }}>
            您正在尝试取消勾选 <strong>"/role-permissions"</strong> 路由权限。
          </p>
          <p style={{ marginBottom: '16px', fontSize: '14px', lineHeight: '1.6' }}>
            <strong>请注意：</strong>如果取消此路由权限，该角色的用户将无法访问角色权限管理页面，这可能导致无法管理系统权限。
          </p>
          <p style={{ marginBottom: '16px', fontSize: '14px', color: '#666' }}>
            请谨慎操作，确认后需要点击"保存权限"才会生效。
          </p>

          <div style={{ display: 'flex', gap: '12px', justifyContent: 'flex-end', marginTop: '24px' }}>
            <Button
              variant="secondary"
              onClick={() => {
                setShowPermissionWarning(false);
                setPendingRouteChange(null);
              }}
            >
              取消
            </Button>
            <Button
              variant="danger"
              onClick={confirmRemovePermissionRoute}
            >
              确认取消勾选
            </Button>
          </div>
        </div>
      </Modal>
    </div>
  );
}
