package com.srs.flowable.listener.disciplinary;

import com.srs.common.utils.SecurityUtils;
import com.srs.comprehensive.domain.CphMsg;
import com.srs.comprehensive.service.ICphMsgService;
import lombok.extern.slf4j.Slf4j;
import org.flowable.bpmn.model.FlowElement;
import org.flowable.bpmn.model.SequenceFlow;
import org.flowable.engine.delegate.DelegateExecution;
import org.flowable.engine.delegate.ExecutionListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.List;

/**
 * 为即将到来的多实例任务创建内部消息。 知无涯
 * <p>
 * 它只从流程变量 `userList` 中读取接收人列表。
 * </p>
 */
@Component("multiInstanceMessageListener") // 定义一个全新的Bean名称
@Slf4j
public class MultiInstanceMessageListener implements ExecutionListener {

    @Autowired
    private ICphMsgService cphMsgService;

    @Override
    public void notify(DelegateExecution execution) {
        log.info("流程实例 [{}]: 触发多实例专用消息监听器 (MultiInstanceMessageListener)...", execution.getProcessInstanceId());

        // --- 步骤 1: 只从 'userList' 变量获取接收人 ---
        Object userListObj = execution.getVariable("userList");
        if (!(userListObj instanceof List) || ((List<?>) userListObj).isEmpty()) {
            log.warn("流程实例 [{}]: 未能从 'userList' 变量中找到有效的接收人列表，跳过消息创建。", execution.getProcessInstanceId());
            return;
        }

        @SuppressWarnings("unchecked")
        List<Long> receiverIdList = (List<Long>) userListObj;

        // --- 步骤 2: (已修正) 精确获取下一个目标节点的名称和ID ---
        FlowElement nextElement = getNextFlowElement(execution);
        String taskName = (nextElement != null && nextElement.getName() != null) ? nextElement.getName() : "新的待办";
        String activityId = (nextElement != null) ? nextElement.getId() : "unknownActivity";

        // --- 步骤 3: 准备消息内容 ---
        String messageText = "您有一条新的【" + taskName + "】待办任务需要处理。";
        String link = "<a href='https://zhxg.gxsdxy.cn/wab/#/pages/Approval/index'>请点击前往处理</a>。";
        String hiddenIdentifier = String.format("<span id='flow-identifier' data-proc-inst-id='%s' data-activity-id='%s' style='display:none;'></span>",
                execution.getProcessInstanceId(),
                activityId);
        String finalContent = messageText + link + hiddenIdentifier;

        Long senderId = getSenderId();

        // --- 步骤 4: 批量创建消息 ---
        for (Long receiverId : receiverIdList) {
            try {
                CphMsg cphMsg = new CphMsg();
                cphMsg.setReceiver(receiverId);
                cphMsg.setSender(senderId);
                cphMsg.setContent(finalContent);
                cphMsgService.insertCphMsg(cphMsg);
                log.info("已成功为用户 [{}] 创建多实例任务的内部消息 (关联 Activity ID: {})。", receiverId, activityId);
            } catch (Exception e) {
                log.error("为用户 [{}] 创建多实例任务内部消息时发生异常: {}", receiverId, e.getMessage(), e);
            }
        }
    }

    /**
     * 安全地获取线上监听器的下一个目标节点
     */
    private FlowElement getNextFlowElement(DelegateExecution execution) {
        if (execution.getCurrentFlowElement() instanceof SequenceFlow) {
            return ((SequenceFlow) execution.getCurrentFlowElement()).getTargetFlowElement();
        }
        return null;
    }

    /**
     * 安全地获取当前操作的发送人ID。
     */
    private Long getSenderId() {
        try {
            Long userId = SecurityUtils.getUserId();
            return userId != null ? userId : 1L;
        } catch (Exception e) {
            log.warn("在监听器中获取发送人ID时发生异常，使用默认系统管理员ID(1L)。");
            return 1L;
        }
    }
}
