package com.mosquito.project.permission;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.mosquito.project.dto.UpdateActivityRequest;
import com.mosquito.project.service.ActivityService;
import com.mosquito.project.service.RewardService;
import com.mosquito.project.service.RiskService;
import com.mosquito.project.service.SystemService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

/**
 * 审批流服务
 */
@Service
public class ApprovalFlowService {

    private static final Logger log = LoggerFactory.getLogger(ApprovalFlowService.class);

    // 审批状态常量
    public static final String STATUS_PENDING = "PENDING";
    public static final String STATUS_APPROVED = "APPROVED";
    public static final String STATUS_REJECTED = "REJECTED";
    public static final String STATUS_PROCESSING = "PROCESSING";
    public static final String STATUS_CANCELLED = "CANCELLED";

    // 审批动作
    public static final String ACTION_SUBMIT = "SUBMIT";
    public static final String ACTION_APPROVE = "APPROVE";
    public static final String ACTION_REJECT = "REJECT";
    public static final String ACTION_TRANSFER = "TRANSFER";
    public static final String ACTION_DELEGATE = "DELEGATE";

    // 审批节点类型
    public static final String NODE_TYPE_SERIAL = "SERIAL";       // 串行：按顺序审批
    public static final String NODE_TYPE_PARALLEL = "PARALLEL";   // 并行：任一审批人通过即可
    public static final String NODE_TYPE_COUNTERSIGN = "COUNTERSIGN"; // 会签：全部审批人通过

    private final ApprovalFlowRepository flowRepository;
    private final ApprovalRecordRepository recordRepository;
    private final ApprovalHistoryRepository historyRepository;
    private final ObjectMapper objectMapper;
    private final DepartmentRepository departmentRepository;
    private final UserRoleRepository userRoleRepository;
    private final RoleRepository roleRepository;
    private final ActivityService activityService;
    private final RewardService rewardService;
    private final SysUserService sysUserService;
    private final RoleService roleService;
    private final RiskService riskService;
    private final SystemService systemService;

    public ApprovalFlowService(
            ApprovalFlowRepository flowRepository,
            ApprovalRecordRepository recordRepository,
            ApprovalHistoryRepository historyRepository,
            ObjectMapper objectMapper,
            DepartmentRepository departmentRepository,
            UserRoleRepository userRoleRepository,
            RoleRepository roleRepository,
            ActivityService activityService,
            RewardService rewardService,
            SysUserService sysUserService,
            RoleService roleService,
            RiskService riskService,
            SystemService systemService) {
        this.flowRepository = flowRepository;
        this.recordRepository = recordRepository;
        this.historyRepository = historyRepository;
        this.objectMapper = objectMapper;
        this.departmentRepository = departmentRepository;
        this.userRoleRepository = userRoleRepository;
        this.roleRepository = roleRepository;
        this.activityService = activityService;
        this.rewardService = rewardService;
        this.sysUserService = sysUserService;
        this.roleService = roleService;
        this.riskService = riskService;
        this.systemService = systemService;
    }

    /**
     * 提交审批申请
     */
    @Transactional
    public Map<String, Object> submitApproval(Long flowId, String bizType, Long bizId,
                                               String title, Long applicantId, String applyReason) {
        return submitApprovalWithData(flowId, bizType, bizId, title, applicantId, applyReason, null);
    }

    /**
     * 提交审批申请（带业务数据）
     */
    @Transactional
    public Map<String, Object> submitApprovalWithData(Long flowId, String bizType, Long bizId,
                                               String title, Long applicantId, String applyReason, String bizData) {
        // 获取审批流程配置
        Optional<SysApprovalFlow> flowOpt = flowRepository.findById(flowId);
        if (!flowOpt.isPresent()) {
            throw new IllegalArgumentException("审批流程不存在: " + flowId);
        }

        SysApprovalFlow flow = flowOpt.get();
        if (!"ENABLED".equals(flow.getStatus())) {
            throw new IllegalArgumentException("审批流程已禁用");
        }

        // 检查是否已有待处理的审批
        List<SysApprovalRecord> existing = recordRepository.findByBizTypeAndBizId(bizType, bizId);
        for (SysApprovalRecord record : existing) {
            if (STATUS_PENDING.equals(record.getStatus()) || STATUS_PROCESSING.equals(record.getStatus())) {
                throw new IllegalArgumentException("该业务已存在待处理的审批申请");
            }
        }

        // 解析审批节点，获取第一个审批人
        Long firstApproverId = resolveFirstApprover(flow, applicantId);

        // 创建审批记录
        SysApprovalRecord record = new SysApprovalRecord();
        record.setFlowId(flowId);
        record.setBizType(bizType);
        record.setBizId(bizId);
        record.setCurrentNode(0);
        record.setApplicantId(applicantId);
        record.setCurrentApproverId(firstApproverId);
        record.setStatus(STATUS_PROCESSING);
        record.setCreatedAt(LocalDateTime.now());
        record.setUpdatedAt(LocalDateTime.now());
        if (bizData != null) {
            record.setBizData(bizData);
        }

        // 初始化并行/会签审批字段
        String nodeType = flow.getNodeType();
        if (nodeType == null) {
            nodeType = "SERIAL";
        }
        record.setApprovedCount(0);

        // 根据节点类型设置requiredApprovals和approverIds
        if ("PARALLEL".equals(nodeType) || "COUNTERSIGN".equals(nodeType)) {
            // 解析节点获取所有审批人（使用resolveApproverFromNode支持roleCode/approverCodes）
            List<Map<String, Object>> nodes = parseNodes(flow.getNodes());
            List<Long> approverIdList = new ArrayList<>();
            for (Map<String, Object> node : nodes) {
                // 使用resolveApproverFromNode正确解析审批人（支持roleCode/approverCodes）
                Long approverId = resolveApproverFromNode(node, applicantId);
                if (approverId != null) {
                    approverIdList.add(approverId);
                }
            }
            // 会签需要全部审批人通过，并行只需一人通过
            record.setRequiredApprovals("COUNTERSIGN".equals(nodeType) ? approverIdList.size() : 1);
            try {
                record.setApproverIds(new com.fasterxml.jackson.databind.ObjectMapper()
                    .writeValueAsString(approverIdList));
            } catch (com.fasterxml.jackson.core.JsonProcessingException e) {
                record.setApproverIds("[]");
            }
        } else {
            // 串行审批
            record.setRequiredApprovals(1);
        }

        record = recordRepository.save(record);

        // 记录审批历史
        SysApprovalHistory history = new SysApprovalHistory();
        history.setRecordId(record.getId());
        history.setNodeIndex(0);
        history.setApproverId(applicantId);
        history.setAction(ACTION_SUBMIT);
        history.setComment(applyReason);
        history.setCreatedAt(LocalDateTime.now());
        historyRepository.save(history);

        Map<String, Object> result = new HashMap<>();
        result.put("recordId", record.getId());
        result.put("status", record.getStatus());
        result.put("currentNode", record.getCurrentNode());
        result.put("currentApproverId", firstApproverId);
        result.put("nodeType", nodeType);
        return result;
    }

    /**
     * 通过触发事件提交审批
     */
    @Transactional
    public Map<String, Object> submitApprovalByEvent(String triggerEvent, String bizType, Long bizId,
                                                      String title, Long applicantId, String applyReason) {
        return submitApprovalByEvent(triggerEvent, bizType, bizId, title, applicantId, applyReason, null);
    }

    /**
     * 通过触发事件提交审批（带业务数据）
     */
    public Map<String, Object> submitApprovalByEvent(String triggerEvent, String bizType, Long bizId,
                                                      String title, Long applicantId, String applyReason, String bizData) {
        Optional<SysApprovalFlow> flowOpt = flowRepository.findByTriggerEventAndStatus(triggerEvent, "ENABLED");
        if (!flowOpt.isPresent()) {
            throw new IllegalArgumentException("未找到触发事件对应的审批流程: " + triggerEvent);
        }
        return submitApprovalWithData(flowOpt.get().getId(), bizType, bizId, title, applicantId, applyReason, bizData);
    }

    /**
     * 处理审批（支持串行/并行/会签）
     */
    @Transactional
    public Map<String, Object> handleApproval(Long recordId, String action, Long operatorId, String comment) {
        Optional<SysApprovalRecord> recordOpt = recordRepository.findById(recordId);
        if (!recordOpt.isPresent()) {
            throw new IllegalArgumentException("审批记录不存在: " + recordId);
        }

        SysApprovalRecord record = recordOpt.get();
        if (!STATUS_PROCESSING.equals(record.getStatus())) {
            throw new IllegalArgumentException("审批记录状态不是处理中: " + record.getStatus());
        }

        // 获取流程配置
        Optional<SysApprovalFlow> flowOpt = flowRepository.findById(record.getFlowId());
        if (!flowOpt.isPresent()) {
            throw new IllegalArgumentException("审批流程配置不存在");
        }
        SysApprovalFlow flow = flowOpt.get();

        // 获取节点类型
        String nodeType = flow.getNodeType();
        if (nodeType == null) {
            nodeType = NODE_TYPE_SERIAL;
        }

        // 验证审批人权限（并行/会签模式下检查是否在审批人列表中）
        if (!isValidApprover(record, operatorId, nodeType)) {
            throw new IllegalArgumentException("您不是当前审批人，无权处理此审批");
        }

        // 解析节点配置
        List<Map<String, Object>> nodes = parseNodes(flow.getNodes());
        int currentNode = record.getCurrentNode();

        // 记录审批历史
        SysApprovalHistory history = new SysApprovalHistory();
        history.setRecordId(recordId);
        history.setNodeIndex(currentNode);
        history.setApproverId(operatorId);
        history.setAction(action);
        history.setComment(comment);
        history.setCreatedAt(LocalDateTime.now());
        historyRepository.save(history);

        Map<String, Object> result = new HashMap<>();

        if (ACTION_APPROVE.equals(action)) {
            // 处理并行/会签的批准计数
            if (NODE_TYPE_PARALLEL.equals(nodeType) || NODE_TYPE_COUNTERSIGN.equals(nodeType)) {
                int approvedCount = record.getApprovedCount() != null ? record.getApprovedCount() : 0;
                record.setApprovedCount(approvedCount + 1);
            }

            // 根据节点类型处理审批
            if (NODE_TYPE_PARALLEL.equals(nodeType)) {
                // 并行审批：任一通过即可
                record.setStatus(STATUS_APPROVED);
                record.setUpdatedAt(LocalDateTime.now());
                recordRepository.save(record);
                result.put("status", STATUS_APPROVED);
                result.put("message", "审批已通过（并行审批）");
            } else if (NODE_TYPE_COUNTERSIGN.equals(nodeType)) {
                // 会签审批：需要全部通过
                int required = record.getRequiredApprovals() != null ? record.getRequiredApprovals() : nodes.size();
                int approved = record.getApprovedCount() != null ? record.getApprovedCount() : 0;
                if (approved >= required) {
                    record.setStatus(STATUS_APPROVED);
                    record.setUpdatedAt(LocalDateTime.now());
                    recordRepository.save(record);
                    result.put("status", STATUS_APPROVED);
                    result.put("message", "审批已通过（会签完成）");
                } else {
                    record.setUpdatedAt(LocalDateTime.now());
                    recordRepository.save(record);
                    result.put("status", STATUS_PROCESSING);
                    result.put("approvedCount", approved);
                    result.put("requiredCount", required);
                    result.put("message", "等待其他审批人处理（会签审批）");
                }
            } else {
                // 串行审批：按顺序推进
                if (currentNode + 1 >= nodes.size()) {
                    record.setStatus(STATUS_APPROVED);
                    record.setUpdatedAt(LocalDateTime.now());
                    recordRepository.save(record);
                    result.put("status", STATUS_APPROVED);
                    result.put("message", "审批已通过");
                } else {
                    int nextNode = currentNode + 1;
                    Long nextApproverId = resolveNextApprover(nodes, nextNode, record);
                    record.setCurrentNode(nextNode);
                    record.setCurrentApproverId(nextApproverId);
                    record.setUpdatedAt(LocalDateTime.now());
                    recordRepository.save(record);
                    result.put("status", STATUS_PROCESSING);
                    result.put("currentNode", nextNode);
                    result.put("currentApproverId", nextApproverId);
                    result.put("message", "已提交给下一审批人");
                }
            }
        } else if (ACTION_REJECT.equals(action)) {
            // 拒绝
            record.setStatus(STATUS_REJECTED);
            record.setUpdatedAt(LocalDateTime.now());
            // P0修复：将拒绝原因和操作人保存到bizData供后续业务回调使用
            try {
                Map<String, Object> rejectData = new HashMap<>();
                rejectData.put("operatorId", operatorId);
                rejectData.put("comment", comment);
                rejectData.put("rejectedAt", LocalDateTime.now().toString());
                record.setBizData(objectMapper.writeValueAsString(rejectData));
            } catch (JsonProcessingException e) {
                log.warn("序列化拒绝数据失败: {}", e.getMessage());
            }
            recordRepository.save(record);
            result.put("status", STATUS_REJECTED);
            result.put("message", "审批已拒绝");
            // P0修复：拒绝后触发业务回调（与通过保持一致的处理模式）
            processAfterRejection(record);
        } else if (ACTION_TRANSFER.equals(action) || ACTION_DELEGATE.equals(action)) {
            // 转交/委托
            // 目标ID在comment中传递，格式: "transfer:userId" 或 "delegate:userId"
            // 也支持带原因的格式: "reason -> transfer:userId" 或 "reason -> delegate:userId"
            Long targetUserId = parseTargetUserIdFromComment(comment, action);
            if (targetUserId != null) {
                record.setCurrentApproverId(targetUserId);
                record.setUpdatedAt(LocalDateTime.now());
                recordRepository.save(record);
                result.put("status", STATUS_PROCESSING);
                result.put("currentApproverId", targetUserId);
                String actionName = ACTION_DELEGATE.equals(action) ? "委托" : "转交";
                result.put("message", "已" + actionName + "给其他审批人");
            } else {
                String actionName = ACTION_DELEGATE.equals(action) ? "委托" : "转交";
                throw new IllegalArgumentException(actionName + "操作需要指定目标审批人，格式: " + action.toLowerCase() + ":userId");
            }
        } else {
            throw new IllegalArgumentException("无效的审批动作: " + action);
        }

        // 审批通过后统一调用业务回调（消除双实现路径）
        if (STATUS_APPROVED.equals(result.get("status"))) {
            processAfterApproval(record);
        }

        return result;
    }

    /**
     * 批量处理审批
     * 支持批量通过/拒绝/转交，返回成功/失败明细
     */
    @Transactional
    public Map<String, Object> batchHandleApproval(List<Long> recordIds, String action, Long operatorId, String comment) {
        Map<String, Object> result = new HashMap<>();
        List<Map<String, Object>> results = new ArrayList<>();
        int successCount = 0;
        int failCount = 0;

        for (Long recordId : recordIds) {
            Map<String, Object> item = new HashMap<>();
            item.put("recordId", recordId);

            try {
                Map<String, Object> handleResult = handleApproval(recordId, action, operatorId, comment);
                item.put("success", true);
                item.put("status", handleResult.get("status"));
                item.put("message", handleResult.get("message"));
                successCount++;
            } catch (Exception e) {
                item.put("success", false);
                item.put("status", "ERROR");
                item.put("message", e.getMessage());
                failCount++;
            }

            results.add(item);
        }

        result.put("results", results);
        result.put("total", recordIds.size());
        result.put("successCount", successCount);
        result.put("failCount", failCount);
        result.put("action", action);

        return result;
    }

    /**
     * 获取待审批列表
     */
    public List<SysApprovalRecord> getPendingApprovals(Long userId) {
        return recordRepository.findPendingByApproverId(userId);
    }

    /**
     * 获取所有待审批列表（不按用户过滤，用于全局统计）
     * 统一查询PENDING和PROCESSING状态，确保与个人待办列表一致
     */
    public List<SysApprovalRecord> getAllPendingApprovals() {
        return recordRepository.findByStatusIn(List.of(STATUS_PENDING, STATUS_PROCESSING));
    }

    /**
     * 审批通过后的业务处理（超时自动审批时调用）
     * 处理活动发布、奖励发放等后续业务
     * 与手工审批走相同的业务回调逻辑
     */
    public void processAfterApproval(SysApprovalRecord record) {
        log.info("处理审批通过后业务, recordId: {}, bizType: {}", record.getId(), record.getBizType());

        // 根据业务类型执行后续处理 - 支持更多业务类型
        String bizType = record.getBizType();
        if (bizType != null) {
            switch (bizType) {
                case "ACTIVITY_CREATE":
                case "ACTIVITY_UPDATE":
                case "ACTIVITY_DELETE":
                case "ACTIVITY_PUBLISH":
                    // 活动相关审批通过后处理
                    processActivityApproval(record);
                    break;
                case "REWARD_GRANT":
                case "REWARD_APPLY":
                case "REWARD_APPROVE":
                    // 奖励相关审批通过后发放
                    processRewardApproval(record);
                    break;
                case "ROLE_CHANGE":
                    // 角色变更审批通过后执行
                    processRoleChangeApproval(record);
                    break;
                case "ROLE_CREATE":
                    // 角色创建审批通过后
                    processRoleCreateApproval(record);
                    break;
                case "ROLE_UPDATE":
                    // 角色更新审批通过后
                    processRoleUpdateApproval(record);
                    break;
                case "ROLE_DELETE":
                    // 角色删除审批通过后
                    processRoleDeleteApproval(record);
                    break;
                case "USER_FREEZE":
                    // 用户冻结审批通过后执行
                    processUserFreezeApproval(record);
                    break;
                case "USER_UNFREEZE":
                    // 用户解冻审批通过后执行
                    processUserUnfreezeApproval(record);
                    break;
                case "USER_DELETE":
                    // 用户删除审批通过后执行
                    processUserDeleteApproval(record);
                    break;
                case "API_KEY_CREATE":
                case "API_KEY_UPDATE":
                case "API_KEY_DELETE":
                case "API_KEY_APPLY": // 统一处理API Key申请，与ApprovalController保持一致
                    // API Key 相关审批通过后处理
                    processApiKeyApproval(record);
                    break;
                case "RISK_RULE_CREATE":
                case "RISK_RULE_UPDATE":
                case "RISK_RULE_DELETE":
                    // 风控规则相关审批通过后处理
                    processRiskRuleApproval(record);
                    break;
                case "PERMISSION_CHANGE":
                    // 权限变更审批通过后执行
                    processPermissionChangeApproval(record);
                    break;
                case "SYSTEM_CONFIG":
                case "SYSTEM_CONFIG_BATCH":
                case "SYSTEM_CONFIG_RESET":
                    // 系统配置相关审批通过后处理
                    processSystemConfigApproval(record);
                    break;
                default:
                    log.warn("未知的业务类型: {}, 跳过业务处理", bizType);
                    break;
            }
        }

        log.info("审批通过后业务处理完成, recordId: {}", record.getId());
    }

    /**
     * 审批拒绝后的业务处理（超时自动审批时调用）
     */
    public void processAfterRejection(SysApprovalRecord record) {
        log.info("处理审批拒绝后业务, recordId: {}, bizType: {}", record.getId(), record.getBizType());

        // 根据业务类型执行后续处理 - 支持更多业务类型
        String bizType = record.getBizType();
        if (bizType != null) {
            if (bizType.startsWith("ACTIVITY")) {
                // 活动相关审批拒绝后通知申请人
                processActivityRejection(record);
            } else if (bizType.startsWith("REWARD")) {
                // 奖励相关审批拒绝后通知申请人
                processRewardRejection(record);
            }
            // 可扩展其他业务类型
        }

        log.info("审批拒绝后业务处理完成, recordId: {}", record.getId());
    }

    /**
     * 处理活动审批通过 - 根据业务类型执行不同操作
     */
    private void processActivityApproval(SysApprovalRecord record) {
        try {
            Long activityId = record.getBizId();
            String bizType = record.getBizType();
            log.info("活动审批通过，自动执行操作: activityId={}, bizType={}", activityId, bizType);

            if ("ACTIVITY_DELETE".equals(bizType)) {
                // 活动删除审批通过后执行删除
                activityService.applyActivityDelete(activityId);
                log.info("活动审批通过，活动已删除: activityId={}", activityId);
            } else if ("ACTIVITY_UPDATE".equals(bizType)) {
                // 活动更新审批通过后应用更新内容（而非发布活动）
                // 从 bizData 中解析更新内容
                String bizData = record.getBizData();
                if (bizData != null && !bizData.isEmpty()) {
                    try {
                        UpdateActivityRequest updateRequest = objectMapper.readValue(bizData, UpdateActivityRequest.class);
                        activityService.applyActivityUpdate(activityId, updateRequest);
                        log.info("活动审批通过，活动更新已生效: activityId={}", activityId);
                    } catch (JsonProcessingException e) {
                        log.warn("解析活动更新数据失败: {}", e.getMessage());
                        // 无业务数据，仅刷新缓存
                        activityService.evictActivityCache(activityId);
                    }
                } else {
                    // 无业务数据，仅刷新缓存
                    activityService.evictActivityCache(activityId);
                }
            } else {
                // P0修复：先设置状态为APPROVED/WAITING_PUBLISH，再执行发布
                // 审批通过后先将活动状态设为待发布，避免状态前置失败
                activityService.approveActivity(activityId, false);
                log.info("活动审批通过，已设置待发布状态: activityId={}", activityId);
                // 再执行发布操作
                activityService.publishActivity(activityId);
                log.info("活动审批通过，活动已发布: activityId={}", activityId);
            }
        } catch (Exception e) {
            log.error("活动审批通过回调失败: recordId={}, activityId={}, error={}",
                record.getId(), record.getBizId(), e.getMessage(), e);
        }
    }

    /**
     * 处理活动审批拒绝
     * P0修复：实际执行业务回写，将活动状态设为REJECTED
     */
    @SuppressWarnings("unchecked")
    private void processActivityRejection(SysApprovalRecord record) {
        try {
            Long activityId = record.getBizId();
            // P0修复：从bizData中解析拒绝原因
            String reason = "审批拒绝";
            Long operatorId = null;
            String bizData = record.getBizData();
            if (bizData != null && !bizData.isEmpty()) {
                try {
                    Map<String, Object> rejectData = objectMapper.readValue(bizData, new TypeReference<Map<String, Object>>() {});
                    reason = (String) rejectData.getOrDefault("comment", "审批拒绝");
                    Object opId = rejectData.get("operatorId");
                    if (opId instanceof Integer) {
                        operatorId = ((Integer) opId).longValue();
                    } else if (opId instanceof Long) {
                        operatorId = (Long) opId;
                    }
                } catch (Exception e) {
                    log.warn("解析拒绝数据失败: {}", e.getMessage());
                }
            }
            log.info("活动审批拒绝回调, activityId={}, reason={}, operatorId={}", activityId, reason, operatorId);
            activityService.rejectActivity(activityId, reason);
            log.info("活动审批拒绝已完成, activityId={}", activityId);
        } catch (Exception e) {
            log.error("活动审批拒绝回调失败: recordId={}, activityId={}, error={}",
                record.getId(), record.getBizId(), e.getMessage(), e);
        }
    }

    /**
     * 处理奖励审批通过 - 触发奖励发放
     * 注意：奖励发放逻辑已在RewardService.approveReward中统一处理
     * 此处仅作日志记录，避免重复发放
     */
    private void processRewardApproval(SysApprovalRecord record) {
        try {
            Long rewardId = record.getBizId();
            log.info("奖励审批通过回调: rewardId={}", rewardId);
            // 奖励发放已在审批通过时统一处理（RewardService.approveReward中已设置为GRANTED）
            // 此处仅记录审计日志
            log.info("奖励审批通过并已发放: rewardId={}", rewardId);
        } catch (Exception e) {
            log.error("奖励审批通过回调失败: recordId={}, rewardId={}, error={}",
                record.getId(), record.getBizId(), e.getMessage(), e);
        }
    }

    /**
     * 处理奖励审批拒绝
     */
    private void processRewardRejection(SysApprovalRecord record) {
        log.debug("奖励审批拒绝待处理, rewardId: {}", record.getBizId());
    }

    /**
     * 处理角色变更审批通过
     * P0修复：实际执行角色变更落库逻辑
     */
    @SuppressWarnings("unchecked")
    private void processRoleChangeApproval(SysApprovalRecord record) {
        log.info("角色变更审批通过, recordId: {}, bizId: {}", record.getId(), record.getBizId());

        Long userId = record.getBizId();
        String bizData = record.getBizData();

        if (bizData == null || bizData.isEmpty()) {
            log.warn("角色变更审批缺少业务数据, recordId: {}, userId: {}", record.getId(), userId);
            return;
        }

        try {
            Map<String, Object> data = objectMapper.readValue(bizData, new TypeReference<Map<String, Object>>() {});
            List<Integer> roleIdsRaw = (List<Integer>) data.get("roleIds");

            if (roleIdsRaw == null || roleIdsRaw.isEmpty()) {
                log.warn("角色变更审批缺少角色ID列表, recordId: {}, userId: {}", record.getId(), userId);
                return;
            }

            // 转换为Long类型
            List<Long> roleIds = roleIdsRaw.stream().map(Long::valueOf).toList();

            // 执行角色变更：先删后建
            userRoleRepository.deleteByUserId(userId);

            for (Long roleId : roleIds) {
                SysUserRole userRole = new SysUserRole();
                userRole.setUserId(userId);
                userRole.setRoleId(roleId);
                // 使用申请人ID作为createdBy（审批流记录中有applicantId）
                userRole.setCreatedBy(record.getApplicantId());
                userRole.setCreatedAt(LocalDateTime.now());
                userRoleRepository.save(userRole);
            }

            log.info("角色变更审批通过并已执行落库, recordId: {}, userId: {}, roleIds: {}", record.getId(), userId, roleIds);
        } catch (Exception e) {
            log.error("处理角色变更审批失败, recordId: {}, userId: {}, error: {}", record.getId(), userId, e.getMessage(), e);
            throw new RuntimeException("处理角色变更审批失败: " + e.getMessage(), e);
        }
    }

    /**
     * 处理角色创建审批通过
     */
    @SuppressWarnings("unchecked")
    private void processRoleCreateApproval(SysApprovalRecord record) {
        log.info("角色创建审批通过, recordId: {}, bizId: {}", record.getId(), record.getBizId());

        String bizData = record.getBizData();
        if (bizData == null || bizData.isEmpty()) {
            log.warn("角色创建审批缺少业务数据, recordId: {}", record.getId());
            return;
        }

        try {
            Map<String, Object> data = objectMapper.readValue(bizData, new TypeReference<Map<String, Object>>() {});
            SysRole role = new SysRole();
            role.setRoleCode((String) data.get("roleCode"));
            role.setRoleName((String) data.get("roleName"));
            if (data.get("roleLevel") != null) {
                role.setRoleLevel(data.get("roleLevel").toString());
            }
            if (data.get("dataScope") != null) {
                role.setDataScope((String) data.get("dataScope"));
            }
            if (data.get("description") != null) {
                role.setDescription((String) data.get("description"));
            }
            if (data.get("status") != null) {
                role.setStatus((String) data.get("status"));
            }

            SysRole savedRole = roleService.save(role);
            log.info("角色创建审批通过并已创建角色: roleId={}, roleCode={}", savedRole.getId(), savedRole.getRoleCode());
        } catch (Exception e) {
            log.error("处理角色创建审批失败, recordId: {}, error: {}", record.getId(), e.getMessage(), e);
            throw new RuntimeException("处理角色创建审批失败: " + e.getMessage(), e);
        }
    }

    /**
     * 处理角色更新审批通过
     */
    @SuppressWarnings("unchecked")
    private void processRoleUpdateApproval(SysApprovalRecord record) {
        log.info("角色更新审批通过, recordId: {}, bizId: {}", record.getId(), record.getBizId());

        Long roleId = record.getBizId();
        String bizData = record.getBizData();
        if (bizData == null || bizData.isEmpty()) {
            log.warn("角色更新审批缺少业务数据, recordId: {}", record.getId());
            return;
        }

        try {
            Map<String, Object> data = objectMapper.readValue(bizData, new TypeReference<Map<String, Object>>() {});
            SysRole roleData = new SysRole();
            if (data.get("roleName") != null) {
                roleData.setRoleName((String) data.get("roleName"));
            }
            if (data.get("roleLevel") != null) {
                roleData.setRoleLevel(data.get("roleLevel").toString());
            }
            if (data.get("dataScope") != null) {
                roleData.setDataScope((String) data.get("dataScope"));
            }
            if (data.get("description") != null) {
                roleData.setDescription((String) data.get("description"));
            }
            if (data.get("status") != null) {
                roleData.setStatus((String) data.get("status"));
            }

            roleService.update(roleId, roleData);
            log.info("角色更新审批通过并已更新角色: roleId={}", roleId);
        } catch (Exception e) {
            log.error("处理角色更新审批失败, recordId: {}, error: {}", record.getId(), e.getMessage(), e);
            throw new RuntimeException("处理角色更新审批失败: " + e.getMessage(), e);
        }
    }

    /**
     * 处理角色删除审批通过
     */
    private void processRoleDeleteApproval(SysApprovalRecord record) {
        log.info("角色删除审批通过, recordId: {}, bizId: {}", record.getId(), record.getBizId());

        Long roleId = record.getBizId();
        try {
            roleService.delete(roleId);
            log.info("角色删除审批通过并已删除角色: roleId={}", roleId);
        } catch (Exception e) {
            log.error("处理角色删除审批失败, recordId: {}, error: {}", record.getId(), e.getMessage(), e);
            throw new RuntimeException("处理角色删除审批失败: " + e.getMessage(), e);
        }
    }

    /**
     * 处理用户冻结审批通过
     */
    private void processUserFreezeApproval(SysApprovalRecord record) {
        log.info("用户冻结审批通过, recordId: {}, bizId: {}", record.getId(), record.getBizId());

        Long userId = record.getBizId();
        try {
            boolean result = sysUserService.freezeUser(userId);
            if (result) {
                log.info("用户冻结审批通过并已冻结用户: userId={}", userId);
            } else {
                log.warn("用户冻结审批通过但冻结操作失败: userId={}", userId);
            }
        } catch (Exception e) {
            log.error("处理用户冻结审批失败, recordId: {}, error: {}", record.getId(), e.getMessage(), e);
            throw new RuntimeException("处理用户冻结审批失败: " + e.getMessage(), e);
        }
    }

    /**
     * 处理用户解冻审批通过
     */
    private void processUserUnfreezeApproval(SysApprovalRecord record) {
        log.info("用户解冻审批通过, recordId: {}, bizId: {}", record.getId(), record.getBizId());

        Long userId = record.getBizId();
        try {
            boolean result = sysUserService.unfreezeUser(userId);
            if (result) {
                log.info("用户解冻审批通过并已解冻用户: userId={}", userId);
            } else {
                log.warn("用户解冻审批通过但解冻操作失败: userId={}", userId);
            }
        } catch (Exception e) {
            log.error("处理用户解冻审批失败, recordId: {}, error: {}", record.getId(), e.getMessage(), e);
            throw new RuntimeException("处理用户解冻审批失败: " + e.getMessage(), e);
        }
    }

    /**
     * 处理用户删除审批通过
     */
    private void processUserDeleteApproval(SysApprovalRecord record) {
        log.info("用户删除审批通过, recordId: {}, bizId: {}", record.getId(), record.getBizId());

        Long userId = record.getBizId();
        try {
            sysUserService.deleteUser(userId);
            log.info("用户删除审批通过并已删除用户: userId={}", userId);
        } catch (Exception e) {
            log.error("处理用户删除审批失败, recordId: {}, error: {}", record.getId(), e.getMessage(), e);
            throw new RuntimeException("处理用户删除审批失败: " + e.getMessage(), e);
        }
    }

    /**
     * 处理API Key审批通过
     */
    private void processApiKeyApproval(SysApprovalRecord record) {
        log.info("API Key审批通过, recordId: {}, bizId: {}", record.getId(), record.getBizId());

        Long apiKeyId = record.getBizId();
        String bizType = record.getBizType();
        try {
            if ("API_KEY_APPLY".equals(bizType) || "API_KEY_CREATE".equals(bizType)) {
                // API Key申请/创建审批通过后激活
                String rawKey = activityService.activatePendingApiKey(apiKeyId);
                if (rawKey != null) {
                    log.info("API Key审批通过并已激活: apiKeyId={}", apiKeyId);
                } else {
                    log.warn("API Key审批通过但激活操作失败: apiKeyId={}", apiKeyId);
                }
            } else {
                log.info("API Key其他操作审批通过: bizType={}, apiKeyId={}", bizType, apiKeyId);
            }
        } catch (Exception e) {
            log.error("处理API Key审批失败, recordId: {}, error: {}", record.getId(), e.getMessage(), e);
            throw new RuntimeException("处理API Key审批失败: " + e.getMessage(), e);
        }
    }

    /**
     * 处理风控规则审批通过
     */
    private void processRiskRuleApproval(SysApprovalRecord record) {
        log.info("风控规则审批通过, recordId: {}, bizId: {}", record.getId(), record.getBizId());

        Long ruleId = record.getBizId();
        String bizType = record.getBizType();
        try {
            if ("RISK_RULE_CREATE".equals(bizType) || "RISK_RULE_UPDATE".equals(bizType)) {
                // 风控规则创建/更新审批通过后应用
                boolean result = riskService.applyPendingRule(ruleId);
                if (result) {
                    log.info("风控规则审批通过并已应用: ruleId={}, bizType={}", ruleId, bizType);
                } else {
                    log.warn("风控规则审批通过但应用操作失败: ruleId={}", ruleId);
                }
            } else if ("RISK_RULE_DELETE".equals(bizType)) {
                // 风控规则删除审批通过后删除
                boolean result = riskService.deleteRule(ruleId);
                if (result) {
                    log.info("风控规则删除审批通过并已删除: ruleId={}", ruleId);
                } else {
                    log.warn("风控规则删除审批通过但删除操作失败: ruleId={}", ruleId);
                }
            }
        } catch (Exception e) {
            log.error("处理风控规则审批失败, recordId: {}, error: {}", record.getId(), e.getMessage(), e);
            throw new RuntimeException("处理风控规则审批失败: " + e.getMessage(), e);
        }
    }

    /**
     * 处理系统配置审批通过
     */
    @SuppressWarnings("unchecked")
    private void processSystemConfigApproval(SysApprovalRecord record) {
        log.info("系统配置审批通过, recordId: {}, bizId: {}, bizType: {}", record.getId(), record.getBizId(), record.getBizType());

        String bizType = record.getBizType();
        String bizData = record.getBizData();
        if (bizData == null || bizData.isEmpty()) {
            log.warn("系统配置审批缺少业务数据, recordId: {}", record.getId());
            return;
        }

        try {
            if ("SYSTEM_CONFIG".equals(bizType)) {
                // 单项配置更新审批通过后应用
                Map<String, Object> data = objectMapper.readValue(bizData, new TypeReference<Map<String, Object>>() {});
                String key = (String) data.get("key");
                if (key != null) {
                    boolean result = systemService.applyPendingConfig(key);
                    if (result) {
                        log.info("系统配置审批通过并已应用: key={}", key);
                    } else {
                        log.warn("系统配置审批通过但应用操作失败: key={}", key);
                    }
                }
            } else if ("SYSTEM_CONFIG_BATCH".equals(bizType)) {
                // 批量配置更新审批通过后应用
                Map<String, Object> data = objectMapper.readValue(bizData, new TypeReference<Map<String, Object>>() {});
                Map<String, Object> configs = (Map<String, Object>) data.get("configs");
                if (configs != null && !configs.isEmpty()) {
                    for (String key : configs.keySet()) {
                        systemService.applyPendingConfig(key);
                    }
                    log.info("系统配置批量审批通过并已应用: keys={}", configs.keySet());
                }
            } else if ("SYSTEM_CONFIG_RESET".equals(bizType)) {
                // 配置重置审批通过后执行重置
                Map<String, Object> data = objectMapper.readValue(bizData, new TypeReference<Map<String, Object>>() {});
                String key = (String) data.get("key");
                if (key != null) {
                    boolean result = systemService.resetConfig(key);
                    if (result) {
                        log.info("系统配置重置审批通过并已重置: key={}", key);
                    } else {
                        log.warn("系统配置重置审批通过但重置操作失败: key={}", key);
                    }
                }
            }
        } catch (Exception e) {
            log.error("处理系统配置审批失败, recordId: {}, error: {}", record.getId(), e.getMessage(), e);
            throw new RuntimeException("处理系统配置审批失败: " + e.getMessage(), e);
        }
    }

    /**
     * 处理权限变更审批通过（权限分配/撤销）
     */
    @SuppressWarnings("unchecked")
    private void processPermissionChangeApproval(SysApprovalRecord record) {
        log.info("权限变更审批通过, recordId: {}, bizId: {}", record.getId(), record.getBizId());

        String bizData = record.getBizData();
        if (bizData == null || bizData.isEmpty()) {
            log.warn("权限变更审批缺少业务数据, recordId: {}", record.getId());
            return;
        }

        try {
            Map<String, Object> data = objectMapper.readValue(bizData, new TypeReference<Map<String, Object>>() {});
            Long userId = record.getBizId();
            List<Integer> permissionIdsRaw = (List<Integer>) data.get("permissionIds");
            List<Long> permissionIds = permissionIdsRaw.stream().map(Long::valueOf).collect(Collectors.toList());

            // 从bizData中的operator判断是分配还是撤销，并获取授权人
            Long operator = data.get("operator") != null ? Long.valueOf(data.get("operator").toString()) : record.getApplicantId();

            // 根据bizData中的reason关键字判断是分配还是撤销
            String reason = (String) data.get("reason");
            if (reason != null && reason.contains("撤销")) {
                log.info("执行权限撤销, userId: {}, permissionIds: {}", userId, permissionIds);
                sysUserService.revokePermissions(userId, permissionIds);
            } else {
                log.info("执行权限分配, userId: {}, permissionIds: {}, grantedBy: {}", userId, permissionIds, operator);
                sysUserService.assignPermissions(userId, permissionIds, operator);
            }
        } catch (Exception e) {
            log.error("处理权限变更审批失败, recordId: {}, error: {}", record.getId(), e.getMessage(), e);
            throw new RuntimeException("处理权限变更审批失败: " + e.getMessage(), e);
        }
    }

    /**
     * 获取已审批列表（我审批过的）
     */
    public List<SysApprovalRecord> getApprovedList(Long userId) {
        return recordRepository.findProcessedByApproverId(userId);
    }

    /**
     * 获取我发起的审批
     */
    public List<SysApprovalRecord> getMyApplications(Long userId) {
        return recordRepository.findByApplicantId(userId);
    }

    /**
     * 获取审批记录详情
     */
    public Map<String, Object> getRecordById(Long recordId) {
        Optional<SysApprovalRecord> recordOpt = recordRepository.findById(recordId);
        if (!recordOpt.isPresent()) {
            return null;
        }

        SysApprovalRecord record = recordOpt.get();
        Map<String, Object> result = new HashMap<>();
        result.put("id", record.getId());
        result.put("flowId", record.getFlowId());
        result.put("bizType", record.getBizType());
        result.put("bizId", record.getBizId());
        result.put("currentNode", record.getCurrentNode());
        result.put("applicantId", record.getApplicantId());
        result.put("status", record.getStatus());
        result.put("currentApproverId", record.getCurrentApproverId());
        result.put("createdAt", record.getCreatedAt());
        result.put("updatedAt", record.getUpdatedAt());

        // 获取流程信息
        Optional<SysApprovalFlow> flowOpt = flowRepository.findById(record.getFlowId());
        if (flowOpt.isPresent()) {
            SysApprovalFlow flow = flowOpt.get();
            result.put("flowName", flow.getFlowName());
            result.put("flowCode", flow.getFlowCode());
        }

        // 获取审批历史
        List<SysApprovalHistory> histories = historyRepository.findByRecordIdOrderByNodeIndexDesc(recordId);
        result.put("history", histories);

        return result;
    }

    /**
     * 获取审批历史
     */
    public List<SysApprovalHistory> getApprovalHistory(Long recordId) {
        return historyRepository.findByRecordIdOrderByNodeIndexDesc(recordId);
    }

    /**
     * 添加审批意见（不改变审批状态）
     * 仅记录一条意见到历史中
     */
    @Transactional
    public SysApprovalHistory addComment(Long recordId, Long operatorId, String comment) {
        Optional<SysApprovalRecord> recordOpt = recordRepository.findById(recordId);
        if (!recordOpt.isPresent()) {
            throw new IllegalArgumentException("审批记录不存在: " + recordId);
        }

        SysApprovalRecord record = recordOpt.get();

        // 创建审批历史记录
        SysApprovalHistory history = new SysApprovalHistory();
        history.setRecordId(recordId);
        history.setNodeIndex(record.getCurrentNode());
        history.setApproverId(operatorId);
        history.setAction("COMMENT");
        history.setComment(comment);
        history.setCreatedAt(LocalDateTime.now());

        return historyRepository.save(history);
    }

    /**
     * 取消审批
     */
    @Transactional
    public boolean cancelApproval(Long recordId, Long operatorId) {
        Optional<SysApprovalRecord> recordOpt = recordRepository.findById(recordId);
        if (!recordOpt.isPresent()) {
            throw new IllegalArgumentException("审批记录不存在: " + recordId);
        }

        SysApprovalRecord record = recordOpt.get();
        if (!operatorId.equals(record.getApplicantId())) {
            throw new IllegalArgumentException("只有申请人可以取消审批");
        }

        if (!STATUS_PROCESSING.equals(record.getStatus())) {
            throw new IllegalArgumentException("只有处理中的审批可以取消");
        }

        record.setStatus(STATUS_CANCELLED);
        record.setUpdatedAt(LocalDateTime.now());
        recordRepository.save(record);
        return true;
    }

    /**
     * 获取所有审批流程配置
     */
    public List<SysApprovalFlow> getAllFlows() {
        return flowRepository.findAll();
    }

    /**
     * 获取启用的审批流程
     */
    public List<SysApprovalFlow> getEnabledFlows() {
        return flowRepository.findByStatus("ENABLED");
    }

    /**
     * 创建审批流程配置
     */
    public SysApprovalFlow createFlow(Map<String, Object> request) {
        SysApprovalFlow flow = new SysApprovalFlow();
        flow.setFlowCode((String) request.get("flowCode"));
        flow.setFlowName((String) request.get("flowName"));
        flow.setTriggerEvent((String) request.get("triggerEvent"));
        flow.setConditions((String) request.get("conditions"));
        flow.setNodes((String) request.get("nodes"));
        flow.setTimeoutHours((Integer) request.getOrDefault("timeoutHours", 24));
        flow.setTimeoutAction((String) request.getOrDefault("timeoutAction", "ESCALATE"));
        flow.setStatus("ENABLED");
        flow.setCreatedAt(java.time.LocalDateTime.now());
        return flowRepository.save(flow);
    }

    /**
     * 更新审批流程配置
     */
    public SysApprovalFlow updateFlow(Long id, Map<String, Object> request) {
        SysApprovalFlow flow = flowRepository.findById(id)
                .orElseThrow(() -> new IllegalArgumentException("审批流程不存在"));

        if (request.containsKey("flowName")) {
            flow.setFlowName((String) request.get("flowName"));
        }
        if (request.containsKey("conditions")) {
            flow.setConditions((String) request.get("conditions"));
        }
        if (request.containsKey("nodes")) {
            flow.setNodes((String) request.get("nodes"));
        }
        if (request.containsKey("timeoutHours")) {
            flow.setTimeoutHours((Integer) request.get("timeoutHours"));
        }
        if (request.containsKey("timeoutAction")) {
            flow.setTimeoutAction((String) request.get("timeoutAction"));
        }

        return flowRepository.save(flow);
    }

    /**
     * 删除审批流程配置
     */
    public void deleteFlow(Long id) {
        if (!flowRepository.existsById(id)) {
            throw new IllegalArgumentException("审批流程不存在");
        }
        flowRepository.deleteById(id);
    }

    /**
     * 启用/禁用审批流程
     */
    public SysApprovalFlow toggleFlowStatus(Long id, Boolean enabled) {
        SysApprovalFlow flow = flowRepository.findById(id)
                .orElseThrow(() -> new IllegalArgumentException("审批流程不存在"));
        flow.setStatus(enabled ? "ENABLED" : "DISABLED");
        return flowRepository.save(flow);
    }

    /**
     * 根据ID获取审批流程配置
     */
    public SysApprovalFlow getFlowById(Long id) {
        return flowRepository.findById(id)
                .orElseThrow(() -> new IllegalArgumentException("审批流程不存在"));
    }

    /**
     * 根据触发事件获取启用的审批流程
     * 用于获取冻结/解冻等特定业务类型的审批流程
     */
    public SysApprovalFlow getFlowByTriggerEvent(String triggerEvent) {
        return flowRepository.findEnabledByTriggerEvent(triggerEvent)
                .orElse(null);
    }

    /**
     * 验证审批人是否有权处理该审批
     */
    private boolean isValidApprover(SysApprovalRecord record, Long operatorId, String nodeType) {
        // 串行审批：只检查当前审批人
        if (NODE_TYPE_SERIAL.equals(nodeType)) {
            return operatorId.equals(record.getCurrentApproverId());
        }

        // 并行/会签审批：检查是否在审批人列表中
        String approverIds = record.getApproverIds();
        if (approverIds != null && !approverIds.isEmpty()) {
            try {
                List<Long> approverIdList = objectMapper.readValue(approverIds,
                    objectMapper.getTypeFactory().constructCollectionType(List.class, Long.class));
                return approverIdList.contains(operatorId);
            } catch (JsonProcessingException e) {
                // 解析失败，回退到原有逻辑
                return operatorId.equals(record.getCurrentApproverId());
            }
        }

        return operatorId.equals(record.getCurrentApproverId());
    }

    /**
     * 解析节点配置JSON
     */
    @SuppressWarnings("unchecked")
    private List<Map<String, Object>> parseNodes(String nodesJson) {
        try {
            return objectMapper.readValue(nodesJson, List.class);
        } catch (JsonProcessingException e) {
            throw new IllegalArgumentException("审批节点配置解析失败", e);
        }
    }

    /**
     * 解析第一个审批人
     */
    private Long resolveFirstApprover(SysApprovalFlow flow, Long applicantId) {
        List<Map<String, Object>> nodes = parseNodes(flow.getNodes());
        if (nodes.isEmpty()) {
            throw new IllegalArgumentException("审批流程节点配置为空");
        }
        return resolveApproverFromNode(nodes.get(0), applicantId);
    }

    /**
     * 解析下一个审批人
     */
    private Long resolveNextApprover(List<Map<String, Object>> nodes, int nodeIndex, SysApprovalRecord record) {
        if (nodeIndex >= nodes.size()) {
            return null;
        }
        return resolveApproverFromNode(nodes.get(nodeIndex), record.getApplicantId());
    }

    /**
     * 从节点配置中解析审批人
     * 支持两种协议：
     * 1. roleCode: 根据角色代码查找用户
     * 2. approverCodes: 直接指定用户ID列表（兼容旧模板数据）
     */
    @SuppressWarnings("unchecked")
    private Long resolveApproverFromNode(Map<String, Object> node, Long applicantId) {
        String approverType = (String) node.get("approverType");
        if ("SELF".equals(approverType)) {
            return applicantId;
        } else if ("ROLE".equals(approverType)) {
            // 根据角色代码查找用户
            Object roleCodeObj = node.get("roleCode");
            if (roleCodeObj != null) {
                String roleCode = roleCodeObj.toString();
                return findUserIdByRoleCode(roleCode);
            }
            // 兼容：检查 approverCodes（可能是单个用户ID或JSON数组）
            Object approverCodesObj = node.get("approverCodes");
            if (approverCodesObj != null) {
                return resolveApproverFromCodes(approverCodesObj);
            }
            return null;
        } else if ("DEPARTMENT_HEAD".equals(approverType)) {
            // 查找申请人所在部门的负责人
            return findDepartmentHeadByApplicantId(applicantId);
        } else if ("SPECIFIC".equals(approverType)) {
            // 指定用户
            Object approverId = node.get("approverId");
            if (approverId != null) {
                return ((Number) approverId).longValue();
            }
            // 兼容：检查 approverCodes
            Object approverCodesObj = node.get("approverCodes");
            if (approverCodesObj != null) {
                return resolveApproverFromCodes(approverCodesObj);
            }
        }
        // 默认返回null，需要手动分配
        return null;
    }

    /**
     * 从 approverCodes 字段解析审批人ID
     * 支持格式：
     * - 数字ID: 123
     * - 字符串数字: "123"
     * - JSON数组: [123, 456]
     * - 逗号分隔: "123,456"
     * - 角色码字符串: "risk_manager" (当 approverType 为 ROLE 时)
     * - JSON角色码数组: ["risk_manager"] (当 approverType 为 ROLE 时)
     */
    private Long resolveApproverFromCodes(Object approverCodesObj) {
        if (approverCodesObj instanceof Number) {
            return ((Number) approverCodesObj).longValue();
        } else if (approverCodesObj instanceof String) {
            String codes = (String) approverCodesObj;
            // 尝试解析为数字
            try {
                return Long.parseLong(codes);
            } catch (NumberFormatException e) {
                // 可能是逗号分隔的多个ID，取第一个
                String[] parts = codes.split(",");
                if (parts.length > 0) {
                    try {
                        return Long.parseLong(parts[0].trim());
                    } catch (NumberFormatException ignored) {
                        // 可能是角色码，返回null由调用方处理
                        return null;
                    }
                }
            }
        } else if (approverCodesObj instanceof List) {
            List<?> codesList = (List<?>) approverCodesObj;
            if (!codesList.isEmpty()) {
                Object first = codesList.get(0);
                if (first instanceof Number) {
                    return ((Number) first).longValue();
                } else if (first instanceof String) {
                    String strValue = (String) first;
                    // 尝试解析为数字
                    try {
                        return Long.parseLong(strValue);
                    } catch (NumberFormatException ignored) {
                        // 可能是角色码，尝试通过角色码查找用户ID
                        return findUserIdByRoleCode(strValue);
                    }
                }
            }
        }
        return null;
    }

    /**
     * 根据申请人ID查找其所在部门的负责人
     */
    private Long findDepartmentHeadByApplicantId(Long applicantId) {
        // 查找用户的部门ID
        List<SysUserRole> userRoles = userRoleRepository.findByUserId(applicantId);
        if (userRoles == null || userRoles.isEmpty()) {
            return null;
        }

        // 获取第一个非空的部门ID
        Long departmentId = null;
        for (SysUserRole ur : userRoles) {
            if (ur.getDepartmentId() != null) {
                departmentId = ur.getDepartmentId();
                break;
            }
        }

        if (departmentId == null) {
            return null;
        }

        // 查找部门负责人
        Optional<SysDepartment> deptOpt = departmentRepository.findById(departmentId);
        if (deptOpt.isEmpty()) {
            return null;
        }

        return deptOpt.get().getLeaderId();
    }

    /**
     * 根据角色代码查找用户ID
     */
    private Long findUserIdByRoleCode(String roleCode) {
        // 角色码标准化（别名映射兜底）
        String normalizedRoleCode = normalizeRoleCode(roleCode);

        // 查找角色ID
        var roleOpt = roleRepository.findByRoleCodeAndDeleted(normalizedRoleCode, 0);
        if (roleOpt.isEmpty()) {
            return null;
        }
        Long roleId = roleOpt.get().getId();

        // 查找拥有该角色的第一个用户
        var userRoles = userRoleRepository.findByRoleId(roleId);
        if (userRoles != null && !userRoles.isEmpty()) {
            return userRoles.get(0).getUserId();
        }
        return null;
    }

    /**
     * 角色码标准化（别名映射）
     * 将历史别名映射到标准角色码，解决审批模板角色码与系统定义不一致问题
     */
    private String normalizeRoleCode(String roleCode) {
        if (roleCode == null) {
            return null;
        }
        // 别名映射表
        Map<String, String> aliasMap = new HashMap<>();
        aliasMap.put("customer_service_leader", "cs_manager");
        aliasMap.put("cs_leader", "cs_manager");
        aliasMap.put("service_leader", "cs_manager");
        aliasMap.put("ops_director", "operation_director");
        aliasMap.put("ops_manager", "operation_manager");
        aliasMap.put("mkt_director", "marketing_director");
        aliasMap.put("mkt_manager", "marketing_manager");
        aliasMap.put("finance_mgr", "finance_manager");
        aliasMap.put("risk_mgr", "risk_manager");

        return aliasMap.getOrDefault(roleCode, roleCode);
    }

    /**
     * 从comment中解析目标用户ID
     * 支持格式：
     * - "transfer:userId" 或 "delegate:userId"
     * - "reason -> transfer:userId" 或 "reason -> delegate:userId"
     * - "transfer:userId:extra" (userId后可能有额外内容)
     */
    private Long parseTargetUserIdFromComment(String comment, String action) {
        if (comment == null || comment.isBlank()) {
            return null;
        }

        String prefix = action.equals(ACTION_DELEGATE) ? "delegate:" : "transfer:";
        int prefixLen = prefix.length();

        // 查找前缀位置
        int prefixIndex = comment.indexOf(prefix);
        if (prefixIndex == -1) {
            // 尝试不区分大小写查找
            prefixIndex = comment.toLowerCase().indexOf(prefix);
            if (prefixIndex == -1) {
                return null;
            }
        }

        // 从前缀之后开始提取userId
        String userIdPart = comment.substring(prefixIndex + prefixLen);
        // 去掉可能的空格
        userIdPart = userIdPart.trim();
        // 如果有额外内容（如 "reason -> transfer:123:extra"），只取第一部分
        if (userIdPart.contains(":")) {
            userIdPart = userIdPart.substring(0, userIdPart.indexOf(":")).trim();
        }
        if (userIdPart.contains(" ")) {
            userIdPart = userIdPart.substring(0, userIdPart.indexOf(" ")).trim();
        }
        if (userIdPart.contains("-")) {
            userIdPart = userIdPart.substring(0, userIdPart.indexOf("-")).trim();
        }

        try {
            return Long.parseLong(userIdPart);
        } catch (NumberFormatException e) {
            log.warn("解析目标用户ID失败: comment={}, action={}", comment, action);
            return null;
        }
    }

    /**
     * 检查用户是否有已批准的敏感数据导出权限
     * 用于敏感数据导出前的审批检查
     */
    public boolean hasApprovedExport(Long userId) {
        // 查询用户申请的所有敏感导出审批记录
        List<SysApprovalRecord> records = recordRepository.findByApplicantId(userId);

        // 过滤出SENSITIVE_EXPORT类型的已批准记录
        for (SysApprovalRecord record : records) {
            if ("SENSITIVE_EXPORT".equals(record.getBizType()) && STATUS_APPROVED.equals(record.getStatus())) {
                // 检查审批是否在有效期内（例如24小时内）
                if (record.getUpdatedAt() != null) {
                    java.time.LocalDateTime expiryTime = record.getUpdatedAt().plusHours(24);
                    if (java.time.LocalDateTime.now().isBefore(expiryTime)) {
                        return true;
                    }
                }
            }
        }
        return false;
    }
}
