package com.example.demo.service;

import com.example.demo.model.*;
import com.example.demo.repository.InMemoryDataStore;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 核心业务服务层。
 *
 * <p>封装信息管理系统（IMS）的所有业务逻辑，包括用户管理、角色管理、部门管理、
 * 业务数据管理、日志审计、字典管理、系统参数配置等模块。</p>
 *
 * <p>当前基于 {@link InMemoryDataStore} 内存存储运行，不依赖外部数据库。</p>
 */
@Service
public class BusinessService {

    private final InMemoryDataStore store;

    public BusinessService(InMemoryDataStore store) {
        this.store = store;
    }

    // ==================== 用户管理 ====================

    /**
     * 查询用户列表（支持模糊查询）。
     *
     * @param keyword 模糊搜索关键字（用户名、真实姓名）
     * @param page    页码（从 1 开始）
     * @param size    每页条数
     * @return 分页结果
     * @requirement(name="用户管理", id="SRS-IMS_F-001")
     */
    public PageResult<User> queryUsers(String keyword, int page, int size) {
        List<User> list = store.findAllUsers().stream()
                .filter(u -> keyword == null || keyword.isBlank()
                        || u.getUsername().contains(keyword)
                        || u.getRealName().contains(keyword))
                .skip((long) (page - 1) * size)
                .limit(size)
                .collect(Collectors.toList());
        long total = store.findAllUsers().stream()
                .filter(u -> keyword == null || keyword.isBlank()
                        || u.getUsername().contains(keyword)
                        || u.getRealName().contains(keyword))
                .count();
        return new PageResult<>(total, list);
    }

    /**
     * 根据 ID 查询用户。
     *
     * @param id 用户ID
     * @return 用户信息
     * @requirement(name="用户管理", id="SRS-IMS_F-001")
     */
    public User getUserById(Long id) {
        return store.findUserById(id).orElse(null);
    }

    /**
     * 新增用户。
     *
     * @param user 用户信息
     * @return 创建后的用户（含自动生成的ID）
     * @requirement(name="用户管理", id="SRS-IMS_F-001")
     */
    public User createUser(User user) {
        user.setUserId(store.nextUserId());
        if (user.getStatus() == null) {
            user.setStatus(1);
        }
        store.saveUser(user);
        // 记录操作日志
        recordOperationLog("admin", "新增用户：" + user.getUsername());
        return user;
    }

    /**
     * 编辑用户信息。
     *
     * @param id      用户ID
     * @param updated 更新后的用户信息
     * @return 更新后的用户
     * @requirement(name="用户管理", id="SRS-IMS_F-001")
     */
    public User updateUser(Long id, User updated) {
        return store.findUserById(id).map(existing -> {
            if (updated.getUsername() != null) existing.setUsername(updated.getUsername());
            if (updated.getRealName() != null) existing.setRealName(updated.getRealName());
            if (updated.getDeptId() != null) existing.setDeptId(updated.getDeptId());
            if (updated.getRoleId() != null) existing.setRoleId(updated.getRoleId());
            if (updated.getPhone() != null) existing.setPhone(updated.getPhone());
            if (updated.getStatus() != null) existing.setStatus(updated.getStatus());
            store.saveUser(existing);
            recordOperationLog("admin", "编辑用户：" + existing.getUsername());
            return existing;
        }).orElse(null);
    }

    /**
     * 删除用户。
     *
     * @param id 用户ID
     * @return 是否删除成功
     * @requirement(name="用户管理", id="SRS-IMS_F-001")
     */
    public boolean deleteUser(Long id) {
        Optional<User> opt = store.findUserById(id);
        if (opt.isEmpty()) return false;
        store.deleteUserById(id);
        recordOperationLog("admin", "删除用户：" + opt.get().getUsername());
        return true;
    }

    // ==================== 角色管理 ====================

    /**
     * 查询角色列表（支持模糊查询）。
     *
     * @param keyword 模糊搜索关键字
     * @param page    页码
     * @param size    每页条数
     * @return 分页结果
     * @requirement(name="角色管理", id="SRS-IMS_F-002")
     */
    public PageResult<Role> queryRoles(String keyword, int page, int size) {
        List<Role> list = store.findAllRoles().stream()
                .filter(r -> keyword == null || keyword.isBlank()
                        || r.getRoleName().contains(keyword)
                        || r.getRoleCode().contains(keyword))
                .skip((long) (page - 1) * size)
                .limit(size)
                .collect(Collectors.toList());
        long total = store.findAllRoles().stream()
                .filter(r -> keyword == null || keyword.isBlank()
                        || r.getRoleName().contains(keyword)
                        || r.getRoleCode().contains(keyword))
                .count();
        return new PageResult<>(total, list);
    }

    /**
     * 根据 ID 查询角色。
     *
     * @param id 角色ID
     * @return 角色信息
     * @requirement(name="角色管理", id="SRS-IMS_F-002")
     */
    public Role getRoleById(Long id) {
        return store.findRoleById(id).orElse(null);
    }

    /**
     * 新增角色。
     *
     * @param role 角色信息
     * @return 创建后的角色
     * @requirement(name="角色管理", id="SRS-IMS_F-002")
     */
    public Role createRole(Role role) {
        role.setRoleId(store.nextRoleId());
        role.setIsSuperAdmin(false);
        if (role.getStatus() == null) role.setStatus(1);
        if (role.getPermissionCodes() == null) role.setPermissionCodes(new ArrayList<>());
        store.saveRole(role);
        recordOperationLog("admin", "新增角色：" + role.getRoleName());
        return role;
    }

    /**
     * 编辑角色信息。
     *
     * @param id      角色ID
     * @param updated 更新后的角色信息
     * @return 更新后的角色
     * @requirement(name="角色管理", id="SRS-IMS_F-002")
     */
    public Role updateRole(Long id, Role updated) {
        return store.findRoleById(id).map(existing -> {
            if (updated.getRoleName() != null) existing.setRoleName(updated.getRoleName());
            if (updated.getRoleCode() != null) existing.setRoleCode(updated.getRoleCode());
            if (updated.getDescription() != null) existing.setDescription(updated.getDescription());
            if (updated.getStatus() != null) existing.setStatus(updated.getStatus());
            if (updated.getPermissionCodes() != null) existing.setPermissionCodes(updated.getPermissionCodes());
            store.saveRole(existing);
            recordOperationLog("admin", "编辑角色：" + existing.getRoleName());
            return existing;
        }).orElse(null);
    }

    /**
     * 删除角色（超级管理员角色不可删除）。
     *
     * @param id 角色ID
     * @return 操作结果：null-不存在，false-超级管理员不可删除，true-删除成功
     * @requirement(name="角色管理", id="SRS-IMS_F-002")
     */
    public Boolean deleteRole(Long id) {
        Optional<Role> opt = store.findRoleById(id);
        if (opt.isEmpty()) return null;
        if (Boolean.TRUE.equals(opt.get().getIsSuperAdmin())) {
            return false;
        }
        store.deleteRoleById(id);
        recordOperationLog("admin", "删除角色：" + opt.get().getRoleName());
        return true;
    }

    /**
     * 为角色分配权限。
     *
     * @param roleId          角色ID
     * @param permissionCodes 权限标识列表
     * @return 更新后的角色
     * @requirement(name="角色权限分配", id="SRS-IMS_F-006")
     */
    public Role assignPermissions(Long roleId, List<String> permissionCodes) {
        return store.findRoleById(roleId).map(role -> {
            role.setPermissionCodes(permissionCodes);
            store.saveRole(role);
            recordOperationLog("admin", "为角色分配权限：" + role.getRoleName());
            return role;
        }).orElse(null);
    }

    // ==================== 部门管理 ====================

    /**
     * 查询所有部门列表（扁平结构）。
     *
     * @return 部门列表
     * @requirement(name="部门管理", id="SRS-IMS_F-003")
     */
    public List<Dept> getAllDepts() {
        return store.findAllDepts();
    }

    /**
     * 查询部门树形结构。
     *
     * @return 树形结构的部门列表
     * @requirement(name="部门管理", id="SRS-IMS_F-003")
     */
    public List<Dept> getDeptTree() {
        List<Dept> all = store.findAllDepts();
        Map<Long, List<Dept>> parentMap = all.stream()
                .filter(d -> d.getParentId() != null && d.getParentId() > 0)
                .collect(Collectors.groupingBy(Dept::getParentId));
        List<Dept> roots = all.stream()
                .filter(d -> d.getParentId() == null || d.getParentId() == 0L)
                .peek(d -> d.setChildren(buildChildren(d.getDeptId(), parentMap)))
                .collect(Collectors.toList());
        return roots;
    }

    private List<Dept> buildChildren(Long parentId, Map<Long, List<Dept>> parentMap) {
        List<Dept> children = parentMap.getOrDefault(parentId, Collections.emptyList());
        for (Dept child : children) {
            child.setChildren(buildChildren(child.getDeptId(), parentMap));
        }
        return children;
    }

    /**
     * 根据 ID 查询部门。
     *
     * @param id 部门ID
     * @return 部门信息
     * @requirement(name="部门管理", id="SRS-IMS_F-003")
     */
    public Dept getDeptById(Long id) {
        return store.findDeptById(id).orElse(null);
    }

    /**
     * 新增部门。
     *
     * @param dept 部门信息
     * @return 创建后的部门
     * @requirement(name="部门管理", id="SRS-IMS_F-003")
     */
    public Dept createDept(Dept dept) {
        dept.setDeptId(store.nextDeptId());
        if (dept.getParentId() == null) dept.setParentId(0L);
        if (dept.getStatus() == null) dept.setStatus(1);
        store.saveDept(dept);
        recordOperationLog("admin", "新增部门：" + dept.getDeptName());
        return dept;
    }

    /**
     * 编辑部门信息。
     *
     * @param id      部门ID
     * @param updated 更新后的部门信息
     * @return 更新后的部门
     * @requirement(name="部门管理", id="SRS-IMS_F-003")
     */
    public Dept updateDept(Long id, Dept updated) {
        return store.findDeptById(id).map(existing -> {
            if (updated.getDeptName() != null) existing.setDeptName(updated.getDeptName());
            if (updated.getParentId() != null) existing.setParentId(updated.getParentId());
            if (updated.getSortOrder() != null) existing.setSortOrder(updated.getSortOrder());
            if (updated.getStatus() != null) existing.setStatus(updated.getStatus());
            store.saveDept(existing);
            recordOperationLog("admin", "编辑部门：" + existing.getDeptName());
            return existing;
        }).orElse(null);
    }

    /**
     * 删除部门。
     *
     * @param id 部门ID
     * @return 是否删除成功
     * @requirement(name="部门管理", id="SRS-IMS_F-003")
     */
    public boolean deleteDept(Long id) {
        Optional<Dept> opt = store.findDeptById(id);
        if (opt.isEmpty()) return false;
        store.deleteDeptById(id);
        recordOperationLog("admin", "删除部门：" + opt.get().getDeptName());
        return true;
    }

    // ==================== 业务数据管理 ====================

    /**
     * 查询业务数据列表（多条件组合筛选）。
     *
     * @param keyword 关键字
     * @param type    业务类型
     * @param status  业务状态
     * @param page    页码
     * @param size    每页条数
     * @return 分页结果
     * @requirement(name="查询筛选", id="SRS-IMS_F-017")
     */
    public PageResult<BusinessItem> queryBusinessItems(String keyword, String type, String status, int page, int size) {
        List<BusinessItem> filtered = store.findAllBusiness().stream()
                .filter(item -> keyword == null || keyword.isBlank()
                        || item.getTitle().contains(keyword) || item.getContent().contains(keyword))
                .filter(item -> type == null || type.isBlank() || type.equals(item.getType()))
                .filter(item -> status == null || status.isBlank() || status.equals(item.getStatus()))
                .collect(Collectors.toList());
        long total = filtered.size();
        List<BusinessItem> list = filtered.stream()
                .skip((long) (page - 1) * size)
                .limit(size)
                .collect(Collectors.toList());
        return new PageResult<>(total, list);
    }

    /**
     * 根据 ID 查询业务数据。
     *
     * @param id 业务数据ID
     * @return 业务数据
     * @requirement(name="查询筛选", id="SRS-IMS_F-017")
     */
    public BusinessItem getBusinessItemById(Long id) {
        return store.findBusinessById(id).orElse(null);
    }

    /**
     * 新增业务数据。
     *
     * @param item 业务数据
     * @return 创建后的业务数据
     * @requirement(name="业务新增", id="SRS-IMS_F-010")
     */
    public BusinessItem createBusinessItem(BusinessItem item) {
        item.setId(store.nextBusinessId());
        item.setStatus("DRAFT");
        long now = System.currentTimeMillis();
        item.setCreateTime(now);
        item.setUpdateTime(now);
        store.saveBusiness(item);
        recordOperationLog(item.getCreator(), "新增业务数据：" + item.getTitle());
        return item;
    }

    /**
     * 编辑业务数据。
     *
     * @param id      业务数据ID
     * @param updated 更新后的业务数据（仅允许编辑草稿状态的业务）
     * @return 更新后的业务数据，如果非草稿状态则返回 null
     * @requirement(name="业务编辑", id="SRS-IMS_F-011")
     */
    public BusinessItem updateBusinessItem(Long id, BusinessItem updated) {
        return store.findBusinessById(id).map(existing -> {
            if (!"DRAFT".equals(existing.getStatus()) && !"REJECTED".equals(existing.getStatus())) {
                return null;
            }
            if (updated.getTitle() != null) existing.setTitle(updated.getTitle());
            if (updated.getContent() != null) existing.setContent(updated.getContent());
            if (updated.getType() != null) existing.setType(updated.getType());
            existing.setUpdateTime(System.currentTimeMillis());
            store.saveBusiness(existing);
            recordOperationLog(existing.getCreator(), "编辑业务数据：" + existing.getTitle());
            return existing;
        }).orElse(null);
    }

    /**
     * 删除业务数据。
     *
     * @param id 业务数据ID
     * @return 是否删除成功
     * @requirement(name="业务删除", id="SRS-IMS_F-012")
     */
    public boolean deleteBusinessItem(Long id) {
        Optional<BusinessItem> opt = store.findBusinessById(id);
        if (opt.isEmpty()) return false;
        store.deleteBusinessById(id);
        recordOperationLog(opt.get().getCreator(), "删除业务数据：" + opt.get().getTitle());
        return true;
    }

    /**
     * 提交业务数据至审核流程（仅草稿或驳回状态可提交）。
     *
     * @param id 业务数据ID
     * @return 提交后的业务数据
     * @requirement(name="业务提交", id="SRS-IMS_F-013")
     */
    public BusinessItem submitBusinessItem(Long id) {
        return store.findBusinessById(id).map(item -> {
            if (!"DRAFT".equals(item.getStatus()) && !"REJECTED".equals(item.getStatus())) {
                return null;
            }
            item.setStatus("SUBMITTED");
            item.setReviewComment(null);
            item.setUpdateTime(System.currentTimeMillis());
            store.saveBusiness(item);
            recordOperationLog(item.getCreator(), "提交业务数据审核：" + item.getTitle());
            return item;
        }).orElse(null);
    }

    /**
     * 审核通过业务数据。
     *
     * @param id      业务数据ID
     * @param comment 审核意见
     * @return 审核后的业务数据
     * @requirement(name="业务审核", id="SRS-IMS_F-014")
     */
    public BusinessItem approveBusinessItem(Long id, String comment) {
        return store.findBusinessById(id).map(item -> {
            if (!"SUBMITTED".equals(item.getStatus())) {
                return null;
            }
            item.setStatus("APPROVED");
            item.setReviewComment(comment);
            item.setUpdateTime(System.currentTimeMillis());
            store.saveBusiness(item);
            recordOperationLog("admin", "审核通过：" + item.getTitle());
            return item;
        }).orElse(null);
    }

    /**
     * 驳回业务数据。
     *
     * @param id      业务数据ID
     * @param comment 驳回原因
     * @return 驳回后的业务数据
     * @requirement(name="业务驳回", id="SRS-IMS_F-015")
     */
    public BusinessItem rejectBusinessItem(Long id, String comment) {
        return store.findBusinessById(id).map(item -> {
            if (!"SUBMITTED".equals(item.getStatus())) {
                return null;
            }
            item.setStatus("REJECTED");
            item.setReviewComment(comment);
            item.setUpdateTime(System.currentTimeMillis());
            store.saveBusiness(item);
            recordOperationLog("admin", "驳回业务：" + item.getTitle() + "，原因：" + comment);
            return item;
        }).orElse(null);
    }

    /**
     * 归档已审核通过的业务数据。
     *
     * @param id 业务数据ID
     * @return 归档后的业务数据
     * @requirement(name="业务归档", id="SRS-IMS_F-016")
     */
    public BusinessItem archiveBusinessItem(Long id) {
        return store.findBusinessById(id).map(item -> {
            if (!"APPROVED".equals(item.getStatus())) {
                return null;
            }
            item.setStatus("ARCHIVED");
            item.setUpdateTime(System.currentTimeMillis());
            store.saveBusiness(item);
            recordOperationLog("admin", "归档业务数据：" + item.getTitle());
            return item;
        }).orElse(null);
    }

    // ==================== 数据统计分析 ====================

    /**
     * 数据汇总：按业务类型统计数量。
     *
     * @return 类型->数量的映射
     * @requirement(name="数据汇总", id="SRS-IMS_F-018")
     */
    public Map<String, Long> getBusinessSummary() {
        List<BusinessItem> all = store.findAllBusiness();
        return all.stream()
                .collect(Collectors.groupingBy(BusinessItem::getType, Collectors.counting()));
    }

    /**
     * 图表展示数据：按业务状态统计数量。
     *
     * @return 状态->数量的映射
     * @requirement(name="图表展示", id="SRS-IMS_F-019")
     */
    public Map<String, Long> getChartData() {
        List<BusinessItem> all = store.findAllBusiness();
        return all.stream()
                .collect(Collectors.groupingBy(BusinessItem::getStatus, Collectors.counting()));
    }

    /**
     * 自定义查询：根据自定义条件过滤业务数据。
     *
     * @param conditions 查询条件（key=字段, value=值）
     * @return 符合条件的业务数据列表
     * @requirement(name="自定义查询", id="SRS-IMS_F-020")
     */
    public List<BusinessItem> customQuery(Map<String, String> conditions) {
        List<BusinessItem> all = store.findAllBusiness();
        if (conditions == null || conditions.isEmpty()) {
            return all;
        }
        return all.stream()
                .filter(item -> conditions.entrySet().stream().allMatch(entry -> {
                    String key = entry.getKey();
                    String value = entry.getValue();
                    if (value == null || value.isBlank()) return true;
                    switch (key) {
                        case "title": return item.getTitle() != null && item.getTitle().contains(value);
                        case "type": return item.getType() != null && item.getType().equals(value);
                        case "status": return item.getStatus() != null && item.getStatus().equals(value);
                        case "creator": return item.getCreator() != null && item.getCreator().contains(value);
                        default: return true;
                    }
                }))
                .collect(Collectors.toList());
    }

    /**
     * 报表导出：返回所有业务数据的完整列表（模拟导出数据源）。
     *
     * @return 业务数据列表
     * @requirement(name="报表导出", id="SRS-IMS_F-021")
     */
    public List<BusinessItem> exportReport() {
        return store.findAllBusiness();
    }

    /**
     * 数据台账生成：按类型分组生成结构化台账。
     *
     * @return 台账数据（按类型分组的业务数据列表）
     * @requirement(name="数据台账生成", id="SRS-IMS_F-022")
     */
    public Map<String, List<BusinessItem>> generateLedger() {
        List<BusinessItem> all = store.findAllBusiness();
        return all.stream()
                .collect(Collectors.groupingBy(BusinessItem::getType, LinkedHashMap::new, Collectors.toList()));
    }

    // ==================== 日志审计管理 ====================

    /**
     * 记录登录日志。
     *
     * @param username 用户名
     * @param ip       IP地址
     * @param result   登录结果
     * @requirement(name="登录日志记录", id="SRS-IMS_F-023")
     */
    public void recordLoginLog(String username, String ip, String result) {
        LogRecord log = new LogRecord(store.nextLogId(), "LOGIN", username,
                "用户登录系统", ip, result, null, System.currentTimeMillis());
        store.saveLog(log);
    }

    /**
     * 记录操作日志。
     *
     * @param username 操作用户
     * @param content  操作内容
     * @requirement(name="操作日志记录", id="SRS-IMS_F-024")
     */
    public void recordOperationLog(String username, String content) {
        LogRecord log = new LogRecord(store.nextLogId(), "OPERATION", username,
                content, "127.0.0.1", "SUCCESS", null, System.currentTimeMillis());
        store.saveLog(log);
    }

    /**
     * 记录异常日志。
     *
     * @param username       操作用户
     * @param exceptionDetail 异常详情
     * @requirement(name="异常日志记录", id="SRS-IMS_F-025")
     */
    public void recordExceptionLog(String username, String exceptionDetail) {
        LogRecord log = new LogRecord(store.nextLogId(), "EXCEPTION", username,
                "系统异常", "127.0.0.1", "FAIL", exceptionDetail, System.currentTimeMillis());
        store.saveLog(log);
    }

    /**
     * 日志溯源查询：多条件组合查询日志。
     *
     * @param logType  日志类型（LOGIN/OPERATION/EXCEPTION）
     * @param username 操作用户
     * @param keyword  关键字
     * @param page     页码
     * @param size     每页条数
     * @return 分页结果
     * @requirement(name="日志溯源查询", id="SRS-IMS_F-026")
     */
    public PageResult<LogRecord> queryLogs(String logType, String username, String keyword, int page, int size) {
        List<LogRecord> filtered = store.findAllLogs().stream()
                .filter(log -> logType == null || logType.isBlank() || logType.equals(log.getLogType()))
                .filter(log -> username == null || username.isBlank() || log.getUsername().contains(username))
                .filter(log -> keyword == null || keyword.isBlank()
                        || log.getContent().contains(keyword) || log.getExceptionDetail() != null && log.getExceptionDetail().contains(keyword))
                .sorted((a, b) -> Long.compare(b.getOperateTime(), a.getOperateTime()))
                .collect(Collectors.toList());
        long total = filtered.size();
        List<LogRecord> list = filtered.stream()
                .skip((long) (page - 1) * size)
                .limit(size)
                .collect(Collectors.toList());
        return new PageResult<>(total, list);
    }

    // ==================== 菜单/按钮/数据权限 ====================

    /**
     * 根据角色ID获取动态菜单树。
     *
     * @param roleId 角色ID
     * @return 菜单树列表
     * @requirement(name="菜单权限管理", id="SRS-IMS_F-007")
     */
    public List<TreeNode> getMenusByRole(Long roleId) {
        Optional<Role> roleOpt = store.findRoleById(roleId);
        if (roleOpt.isEmpty()) return Collections.emptyList();
        Role role = roleOpt.get();
        List<TreeNode> fullTree = store.getPermissionTree();
        // 超级管理员返回完整菜单
        if (Boolean.TRUE.equals(role.getIsSuperAdmin())) {
            return fullTree;
        }
        List<String> permissionCodes = role.getPermissionCodes();
        if (permissionCodes == null || permissionCodes.isEmpty()) {
            return Collections.emptyList();
        }
        // 过滤出有权限的菜单及子节点
        return filterMenuByPermissions(fullTree, permissionCodes);
    }

    private List<TreeNode> filterMenuByPermissions(List<TreeNode> nodes, List<String> permissions) {
        List<TreeNode> result = new ArrayList<>();
        for (TreeNode node : nodes) {
            TreeNode filtered = new TreeNode();
            filtered.setId(node.getId());
            filtered.setLabel(node.getLabel());
            filtered.setType(node.getType());
            filtered.setPermissionCode(node.getPermissionCode());
            filtered.setParentId(node.getParentId());
            filtered.setPath(node.getPath());
            filtered.setIcon(node.getIcon());
            filtered.setSortOrder(node.getSortOrder());
            if ("MENU".equals(node.getType())) {
                if (node.getChildren() != null && !node.getChildren().isEmpty()) {
                    List<TreeNode> filteredChildren = filterMenuByPermissions(node.getChildren(), permissions);
                    if (!filteredChildren.isEmpty()) {
                        filtered.setChildren(filteredChildren);
                        result.add(filtered);
                    }
                }
            } else if ("BUTTON".equals(node.getType())) {
                if (permissions.contains(node.getPermissionCode())) {
                    filtered.setChildren(new ArrayList<>());
                    result.add(filtered);
                }
            } else {
                result.add(filtered);
            }
        }
        return result;
    }

    /**
     * 根据角色ID获取按钮权限标识列表。
     *
     * @param roleId 角色ID
     * @return 按钮权限标识列表
     * @requirement(name="按钮权限管理", id="SRS-IMS_F-008")
     */
    public List<String> getButtonPermissions(Long roleId) {
        Optional<Role> roleOpt = store.findRoleById(roleId);
        if (roleOpt.isEmpty()) return Collections.emptyList();
        Role role = roleOpt.get();
        if (Boolean.TRUE.equals(role.getIsSuperAdmin())) {
            List<TreeNode> fullTree = store.getPermissionTree();
            return collectButtonCodes(fullTree);
        }
        return role.getPermissionCodes() != null ? role.getPermissionCodes() : Collections.emptyList();
    }

    private List<String> collectButtonCodes(List<TreeNode> nodes) {
        List<String> codes = new ArrayList<>();
        for (TreeNode node : nodes) {
            if ("BUTTON".equals(node.getType()) && node.getPermissionCode() != null) {
                codes.add(node.getPermissionCode());
            }
            if (node.getChildren() != null) {
                codes.addAll(collectButtonCodes(node.getChildren()));
            }
        }
        return codes;
    }

    /**
     * 获取完整权限树。
     *
     * @return 完整权限树
     * @requirement(name="角色权限分配", id="SRS-IMS_F-006")
     */
    public List<TreeNode> getFullPermissionTree() {
        return store.getPermissionTree();
    }

    /**
     * 获取用户的数据权限范围（模拟实现：按部门分级）。
     *
     * @param userId 用户ID
     * @return 可访问的部门ID列表
     * @requirement(name="数据权限分级管控", id="SRS-IMS_F-009")
     */
    public List<Long> getDataScope(Long userId) {
        Optional<User> userOpt = store.findUserById(userId);
        if (userOpt.isEmpty()) return Collections.emptyList();
        User user = userOpt.get();
        // 超级管理员（roleId=1）可查看所有数据
        if (user.getRoleId() != null && user.getRoleId() == 1L) {
            return store.findAllDepts().stream().map(Dept::getDeptId).collect(Collectors.toList());
        }
        // 普通用户仅可查看本部门数据
        return Collections.singletonList(user.getDeptId());
    }

    // ==================== 字典管理 ====================

    /**
     * 查询字典列表。
     *
     * @param dictType 字典类型
     * @param keyword  关键字
     * @return 字典列表
     * @requirement(name="字典管理", id="SRS-IMS_F-004")
     */
    public List<DictItem> queryDictItems(String dictType, String keyword) {
        return store.findAllDicts().stream()
                .filter(d -> dictType == null || dictType.isBlank() || dictType.equals(d.getDictType()))
                .filter(d -> keyword == null || keyword.isBlank()
                        || d.getItemKey().contains(keyword) || d.getItemValue().contains(keyword))
                .collect(Collectors.toList());
    }

    /**
     * 新增字典项。
     *
     * @param item 字典项
     * @return 创建后的字典项
     * @requirement(name="字典管理", id="SRS-IMS_F-004")
     */
    public DictItem createDictItem(DictItem item) {
        item.setDictId(store.nextDictId());
        if (item.getStatus() == null) item.setStatus(1);
        store.saveDict(item);
        recordOperationLog("admin", "新增字典项：" + item.getItemKey());
        return item;
    }

    /**
     * 编辑字典项。
     *
     * @param id      字典ID
     * @param updated 更新后的字典项
     * @return 更新后的字典项
     * @requirement(name="字典管理", id="SRS-IMS_F-004")
     */
    public DictItem updateDictItem(Long id, DictItem updated) {
        return store.findDictById(id).map(existing -> {
            if (updated.getDictType() != null) existing.setDictType(updated.getDictType());
            if (updated.getDictTypeName() != null) existing.setDictTypeName(updated.getDictTypeName());
            if (updated.getItemKey() != null) existing.setItemKey(updated.getItemKey());
            if (updated.getItemValue() != null) existing.setItemValue(updated.getItemValue());
            if (updated.getSortOrder() != null) existing.setSortOrder(updated.getSortOrder());
            if (updated.getStatus() != null) existing.setStatus(updated.getStatus());
            store.saveDict(existing);
            recordOperationLog("admin", "编辑字典项：" + existing.getItemKey());
            return existing;
        }).orElse(null);
    }

    /**
     * 删除字典项。
     *
     * @param id 字典ID
     * @return 是否删除成功
     * @requirement(name="字典管理", id="SRS-IMS_F-004")
     */
    public boolean deleteDictItem(Long id) {
        Optional<DictItem> opt = store.findDictById(id);
        if (opt.isEmpty()) return false;
        store.deleteDictById(id);
        recordOperationLog("admin", "删除字典项：" + opt.get().getItemKey());
        return true;
    }

    // ==================== 参数配置 ====================

    /**
     * 查询所有系统参数配置。
     *
     * @return 配置列表
     * @requirement(name="参数配置", id="SRS-IMS_F-005")
     */
    public List<SystemConfig> getAllConfigs() {
        return store.findAllConfigs();
    }

    /**
     * 新增系统参数配置。
     *
     * @param config 配置信息
     * @return 创建后的配置
     * @requirement(name="参数配置", id="SRS-IMS_F-005")
     */
    public SystemConfig createConfig(SystemConfig config) {
        config.setConfigId(store.nextConfigId());
        if (config.getStatus() == null) config.setStatus(1);
        store.saveConfig(config);
        recordOperationLog("admin", "新增参数配置：" + config.getConfigKey());
        return config;
    }

    /**
     * 编辑系统参数配置。
     *
     * @param id      配置ID
     * @param updated 更新后的配置
     * @return 更新后的配置
     * @requirement(name="参数配置", id="SRS-IMS_F-005")
     */
    public SystemConfig updateConfig(Long id, SystemConfig updated) {
        return store.findConfigById(id).map(existing -> {
            if (updated.getConfigKey() != null) existing.setConfigKey(updated.getConfigKey());
            if (updated.getConfigValue() != null) existing.setConfigValue(updated.getConfigValue());
            if (updated.getDescription() != null) existing.setDescription(updated.getDescription());
            if (updated.getStatus() != null) existing.setStatus(updated.getStatus());
            store.saveConfig(existing);
            recordOperationLog("admin", "编辑参数配置：" + existing.getConfigKey());
            return existing;
        }).orElse(null);
    }

    /**
     * 删除系统参数配置。
     *
     * @param id 配置ID
     * @return 是否删除成功
     * @requirement(name="参数配置", id="SRS-IMS_F-005")
     */
    public boolean deleteConfig(Long id) {
        Optional<SystemConfig> opt = store.findConfigById(id);
        if (opt.isEmpty()) return false;
        store.deleteConfigById(id);
        recordOperationLog("admin", "删除参数配置：" + opt.get().getConfigKey());
        return true;
    }

    // ==================== 标准化接口与第三方对接（预留） ====================

    /**
     * 标准化接口预留：获取系统对外提供的标准 API 定义列表。
     *
     * @return 标准接口定义列表
     * @requirement(name="标准化接口预留", id="SRS-IMS_F-027")
     */
    public List<Map<String, String>> getStandardApiDefinitions() {
        List<Map<String, String>> apis = new ArrayList<>();
        apis.add(Map.of("name", "用户同步接口", "method", "POST", "path", "/api/external/user/sync", "version", "v1"));
        apis.add(Map.of("name", "业务数据推送接口", "method", "POST", "path", "/api/external/business/push", "version", "v1"));
        apis.add(Map.of("name", "业务数据拉取接口", "method", "GET", "path", "/api/external/business/pull", "version", "v1"));
        apis.add(Map.of("name", "日志上报接口", "method", "POST", "path", "/api/external/log/report", "version", "v1"));
        return apis;
    }

    /**
     * 第三方数据对接：模拟从外部系统导入数据。
     *
     * @param externalData 外部数据列表
     * @return 导入结果摘要
     * @requirement(name="第三方数据对接", id="SRS-IMS_F-028")
     */
    public Map<String, Object> importExternalData(List<Map<String, String>> externalData) {
        int successCount = 0;
        int failCount = 0;
        if (externalData != null) {
            for (Map<String, String> data : externalData) {
                try {
                    BusinessItem item = new BusinessItem();
                    item.setTitle(data.getOrDefault("title", "外部导入-" + System.currentTimeMillis()));
                    item.setContent(data.getOrDefault("content", ""));
                    item.setType(data.getOrDefault("type", "外部"));
                    item.setCreator("external");
                    item.setStatus("DRAFT");
                    item.setId(store.nextBusinessId());
                    long now = System.currentTimeMillis();
                    item.setCreateTime(now);
                    item.setUpdateTime(now);
                    store.saveBusiness(item);
                    successCount++;
                } catch (Exception e) {
                    failCount++;
                }
            }
        }
        recordOperationLog("system", "第三方数据导入完成，成功：" + successCount + "，失败：" + failCount);
        Map<String, Object> result = new HashMap<>();
        result.put("successCount", successCount);
        result.put("failCount", failCount);
        result.put("total", externalData != null ? externalData.size() : 0);
        return result;
    }

    /**
     * 数据同步：模拟执行数据同步任务。
     *
     * @param syncType 同步类型（PUSH-推送, PULL-拉取）
     * @return 同步结果
     * @requirement(name="数据同步", id="SRS-IMS_F-029")
     */
    public Map<String, Object> executeDataSync(String syncType) {
        Map<String, Object> result = new HashMap<>();
        result.put("syncType", syncType);
        result.put("status", "SUCCESS");
        result.put("syncedCount", 10);
        result.put("startTime", System.currentTimeMillis() - 5000);
        result.put("endTime", System.currentTimeMillis());
        result.put("message", syncType + " 数据同步任务执行完成");
        recordOperationLog("system", "执行数据同步任务，类型：" + syncType);
        return result;
    }
}
