package com.srs.flowable.listener.disciplinary;

import com.srs.common.utils.SecurityUtils;
import com.srs.common.utils.WeChatUtil;
import com.srs.common.utils.spring.SpringUtils;
import com.srs.comprehensive.domain.CphMsg;
import com.srs.comprehensive.service.ICphMsgService;
import com.srs.flowable.mapper.DisciplinaryMapper;
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.stereotype.Component;
import java.util.List;

/**
 * 为“校领导审批”节点做准备 知无涯
 * <p>
 * 它的职责包括：
 * 1. 主动清理上一个节点残留的变量。
 * 2. 查询校领导组成员。
 * 3. 向所有成员发送企业微信通知。
 * 4. 为所有成员创建内部消息。
 * </p>
 */
@Component("schoolLeaderApprovalListener")
@Slf4j
public class SchoolLeaderApprovalListener implements ExecutionListener {

    @Override
    public void notify(DelegateExecution execution) {
        log.info("流程实例 [{}]: 触发 SchoolLeaderApprovalListener (一体化)，为'校领导审批'节点发送所有通知...", execution.getProcessInstanceId());

        // --- 步骤 1: 主动清理上一个节点残留的流程变量 ---
        if (execution.hasVariable("approval")) {
            execution.removeVariable("approval");
            log.info("已清理上一个节点残留的 'approval' 变量。");
        }
        if (execution.hasVariable("userList")) {
            execution.removeVariable("userList");
            log.info("已清理上一个节点残留的 'userList' 变量。");
        }

        try {
            DisciplinaryMapper disciplinaryMapper = SpringUtils.getBean(DisciplinaryMapper.class);
            ICphMsgService cphMsgService = SpringUtils.getBean(ICphMsgService.class);
            WeChatUtil weChatUtil = SpringUtils.getBean(WeChatUtil.class);

            // --- 步骤 2: 查询校领导组成员 ---
            final String LEADER_ROLE_KEY = "xldsp";
            List<Long> userIdList = disciplinaryMapper.getApprovalByRoleKey(LEADER_ROLE_KEY);

            if (userIdList == null || userIdList.isEmpty()) {
                log.warn("根据角色Key '{}' 未找到任何校领导用户，无法发送任何通知。", LEADER_ROLE_KEY);
                return;
            }

            // --- 步骤 3: 发送企业微信通知 (批量) ---
            List<String> userNameList = disciplinaryMapper.getUserNamesByUserIdList(userIdList);
            if (userNameList != null && !userNameList.isEmpty()) {
                String toUser = String.join("|", userNameList);
                String weChatMessage = "校领导您有一条新的学生违纪审批任务待处理，<a href='https://zhxg.gxsdxy.cn/wab/#/pages/Approval/index'>请点击前往处理</a>。";
                weChatUtil.sendTextMessage(toUser, weChatMessage);
                log.info("已成功向校领导 (角色: {}) 发送企业微信通知。", LEADER_ROLE_KEY);
            }

            // --- 步骤 4: (关键) 创建内部消息 (逐条) ---
            FlowElement nextElement = getNextFlowElement(execution);
            String taskName = (nextElement != null && nextElement.getName() != null) ? nextElement.getName() : "校领导审批";
            String activityId = (nextElement != null) ? nextElement.getId() : "Activity_0ftj9eo";

            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 internalMessageContent = messageText + link + hiddenIdentifier;

            Long senderId = SecurityUtils.getUserId() != null ? SecurityUtils.getUserId() : 1L;

            for (Long receiverId : userIdList) {
                CphMsg cphMsg = new CphMsg();
                cphMsg.setReceiver(receiverId);
                cphMsg.setSender(senderId);
                cphMsg.setContent(internalMessageContent);
                cphMsgService.insertCphMsg(cphMsg);
                log.info("已成功为校领导 (userId:{}) 创建内部消息。", receiverId);
            }

        } catch (Exception e) {
            log.error("在 SchoolLeaderApprovalListener 中发送通知时出现异常。错误详情: {}", e.getMessage(), e);
        }
    }

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